public Image get4BitImage(Image im)
    {
        int width = im.getWidth(main_frame);
        int height = im.getHeight(main_frame);

        //////////////////////////////////////////
        /////////// Creating the palette /////////
        //////////////////////////////////////////
        int color_palette[]   = new int[16]; // Holds the color value
        int color_frequency[] = new int[16]; // olds the corresponding color's # of occurences

        for(int i = 0; i < 16; i++)
        {
            color_frequency[i] = -1;
            color_palette[i] = -1;
        }

        ///////////////////////
        // Sort color array  //
        ///////////////////////
        int pix[] = JIPTUtilities.getPixelArray(im);
        int new_pix[] = new int[pix.length];
        JIPTUtilities.quicksort(pix);

        int position = 0;
        for(int i = 0; i < 16; i++)
        {
            // Put current color in array if it isn't already there

            position = (pix.length-position)/16 + position;
            boolean not_found = true;

            while(not_found)
            {
                for(int j = 0; j < color_palette.length; j++)
                {
                    if(color_palette[j] == -1)
                    {
                        color_palette[j] = pix[position];
                        not_found = false;
                        break;
                    }
                }

                position++;
            }
        }


        ///////////////////////
        /// DISPLAY PALETTE ///
        ///////////////////////
       /* for(int i = 0; i < color_palette.length; i++)
        {
            System.out.println("Frequency: " + color_frequency[i] + " Color: " + color_palette[i]);
            for(int j = i*new_pix.length/16; j < (i+1)*new_pix.length/16; j++)
                new_pix[j] = color_palette[i];
        }*/

        /////////////////////////////////
        //// Remap pixels to palette ////
        /////////////////////////////////
        pix = JIPTUtilities.getPixelArray(im); // get original pix order back

        for(int i = 0; i < pix.length; i++)
        {

	        int red1   = (pix[i] >> 16) & 0xff;
	        int green1 = (pix[i] >>  8) & 0xff;
	        int blue1  = (pix[i]      ) & 0xff;

            int minimum_deviation = 999999;
            int index = 0;
            // Map to color with minimum deviation
            for(int j = 0; j < color_palette.length; j++)
            {
	            int red2   = (color_palette[j] >> 16) & 0xff;
	            int green2 = (color_palette[j] >>  8) & 0xff;
	            int blue2  = (color_palette[j]      ) & 0xff;

                int deviation = Math.abs(red1 - red2) + Math.abs(green1 - green2) + Math.abs(blue1 - blue2);
                if(deviation < minimum_deviation)
                {
                    minimum_deviation = deviation;
                    index = j;
                }


            }

            new_pix[i] = color_palette[index];
        }


        Image new_im = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width, height, new_pix, 0, width));
        return new_im;
    }