⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpegencoder.java

📁 基于JPEG图像的数字密写方法 F5算法的JAVA程序
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
                        System.out.println("IO Error: " + e.getMessage());                }                if (c == 0xFF) {                        try                        {                                outStream.write(0);                        }                        catch (IOException e) {                                System.out.println("IO Error: " + e.getMessage());                        }                }                PutBuffer <<= 8;                PutBits -= 8;        }        bufferPutBuffer = PutBuffer;        bufferPutBits = PutBits;        }        void flushBuffer(BufferedOutputStream outStream) {                int PutBuffer = bufferPutBuffer;                int PutBits = bufferPutBits;                while (PutBits >= 8) {                        int c = ((PutBuffer >> 16) & 0xFF);                        try                        {                                outStream.write(c);                        }                        catch (IOException e) {                                System.out.println("IO Error: " + e.getMessage());                        }                        if (c == 0xFF) {                                try {                                        outStream.write(0);                                }                                catch (IOException e) {                                        System.out.println("IO Error: " + e.getMessage());                                }                        }                        PutBuffer <<= 8;                        PutBits -= 8;                }                if (PutBits > 0) {                        int c = ((PutBuffer >> 16) & 0xFF);                        try                        {                                outStream.write(c);                        }                        catch (IOException e) {                                System.out.println("IO Error: " + e.getMessage());                        }                }        }    /*    * Initialisation of the Huffman codes for Luminance and Chrominance.    * This code results in the same tables created in the IJG Jpeg-6a    * library.    */    public void initHuf()    {        DC_matrix0=new int[12][2];        DC_matrix1=new int[12][2];        AC_matrix0=new int[255][2];        AC_matrix1=new int[255][2];        DC_matrix = new Object[2];        AC_matrix = new Object[2];        int p, l, i, lastp, si, code;        int[] huffsize = new int[257];        int[] huffcode= new int[257];        /*        * init of the DC values for the chrominance        * [][0] is the code   [][1] is the number of bit        */        p = 0;        for (l = 1; l <= 16; l++)        {                for (i = 1; i <= bitsDCchrominance[l]; i++)                {                        huffsize[p++] = l;                }        }        huffsize[p] = 0;        lastp = p;        code = 0;        si = huffsize[0];        p = 0;        while(huffsize[p] != 0)        {                while(huffsize[p] == si)                {                        huffcode[p++] = code;                        code++;                }                code <<= 1;                si++;        }        for (p = 0; p < lastp; p++)        {                DC_matrix1[valDCchrominance[p]][0] = huffcode[p];                DC_matrix1[valDCchrominance[p]][1] = huffsize[p];        }        /*        * Init of the AC hufmann code for the chrominance        * matrix [][][0] is the code & matrix[][][1] is the number of bit needed        */        p = 0;        for (l = 1; l <= 16; l++)        {                for (i = 1; i <= bitsACchrominance[l]; i++)                {                        huffsize[p++] = l;                }        }        huffsize[p] = 0;        lastp = p;        code = 0;        si = huffsize[0];        p = 0;        while(huffsize[p] != 0)        {                while(huffsize[p] == si)                {                        huffcode[p++] = code;                        code++;                }                code <<= 1;                si++;        }        for (p = 0; p < lastp; p++)        {                AC_matrix1[valACchrominance[p]][0] = huffcode[p];                AC_matrix1[valACchrominance[p]][1] = huffsize[p];        }        /*        * init of the DC values for the luminance        * [][0] is the code   [][1] is the number of bit        */        p = 0;        for (l = 1; l <= 16; l++)        {                for (i = 1; i <= bitsDCluminance[l]; i++)                {                        huffsize[p++] = l;                }        }        huffsize[p] = 0;        lastp = p;        code = 0;        si = huffsize[0];        p = 0;        while(huffsize[p] != 0)        {                while(huffsize[p] == si)                {                        huffcode[p++] = code;                        code++;                }                code <<= 1;                si++;        }        for (p = 0; p < lastp; p++)        {                DC_matrix0[valDCluminance[p]][0] = huffcode[p];                DC_matrix0[valDCluminance[p]][1] = huffsize[p];        }        /*        * Init of the AC hufmann code for luminance        * matrix [][][0] is the code & matrix[][][1] is the number of bit        */        p = 0;        for (l = 1; l <= 16; l++)        {                for (i = 1; i <= bitsACluminance[l]; i++)                {                        huffsize[p++] = l;                }        }        huffsize[p] = 0;        lastp = p;        code = 0;        si = huffsize[0];        p = 0;        while(huffsize[p] != 0)        {                while(huffsize[p] == si)                {                        huffcode[p++] = code;                        code++;                }                code <<= 1;                si++;        }        for (int q = 0; q < lastp; q++)        {                AC_matrix0[valACluminance[q]][0] = huffcode[q];                AC_matrix0[valACluminance[q]][1] = huffsize[q];        }         DC_matrix[0] = DC_matrix0;        DC_matrix[1] = DC_matrix1;        AC_matrix[0] = AC_matrix0;        AC_matrix[1] = AC_matrix1;    }}/* * JpegInfo - Given an image, sets default information about it and divides * it into its constituant components, downsizing those that need to be. */class JpegInfo{    String Comment;    public Image imageobj;    public int imageHeight;    public int imageWidth;    public int BlockWidth[];    public int BlockHeight[];// the following are set as the default    public int Precision = 8;    public int NumberOfComponents = 3;    public Object Components[];    public int[] CompID = {1, 2, 3};    //public int[] HsampFactor = {1, 1, 1};    //public int[] VsampFactor = {1, 1, 1};    public int[] HsampFactor = {2, 1, 1};    public int[] VsampFactor = {2, 1, 1};    public int[] QtableNumber = {0, 1, 1};    public int[] DCtableNumber = {0, 1, 1};    public int[] ACtableNumber = {0, 1, 1};    public boolean[] lastColumnIsDummy = {false, false, false};    public boolean[] lastRowIsDummy = {false, false, false};    public int Ss = 0;    public int Se = 63;    public int Ah = 0;    public int Al = 0;    public int compWidth[], compHeight[];    public int MaxHsampFactor;    public int MaxVsampFactor;    public JpegInfo(Image image, String comment)    {        Components = new Object[NumberOfComponents];        compWidth = new int[NumberOfComponents];        compHeight = new int[NumberOfComponents];        BlockWidth = new int[NumberOfComponents];        BlockHeight = new int[NumberOfComponents];        imageobj = image;        imageWidth = image.getWidth(null);        imageHeight = image.getHeight(null);        //Comment = "JPEG Encoder Copyright 1998, James R. Weeks and BioElectroMech.  ";        Comment = comment;        getYCCArray();    }    public void setComment(String comment) {        Comment.concat(comment);    }    public String getComment() {        return Comment;    }    /*     * This method creates and fills three arrays, Y, Cb, and Cr using the     * input image.     */    private void getYCCArray()    {        int values[] = new int[imageWidth * imageHeight];        int r, g, b, y, x;// In order to minimize the chance that grabPixels will throw an exception// it may be necessary to grab some pixels every few scanlines and process// those before going for more.  The time expense may be prohibitive.// However, for a situation where memory overhead is a concern, this may be// the only choice.    	PixelGrabber grabber = new PixelGrabber(imageobj.getSource(), 0, 0, imageWidth, imageHeight, values, 0, imageWidth);        MaxHsampFactor = 1;        MaxVsampFactor = 1;        for (y = 0; y < NumberOfComponents; y++) {                MaxHsampFactor = Math.max(MaxHsampFactor, HsampFactor[y]);                MaxVsampFactor = Math.max(MaxVsampFactor, VsampFactor[y]);        }if(false) {        for (y = 0; y < NumberOfComponents; y++) {                compWidth[y] = (((imageWidth%8 != 0) ? ((int) Math.ceil((double) imageWidth/8.0))*8 : imageWidth)/MaxHsampFactor)*HsampFactor[y];                if (compWidth[y] != ((imageWidth/MaxHsampFactor)*HsampFactor[y])) {                        lastColumnIsDummy[y] = true;                }                // results in a multiple of 8 for compWidth                // this will make the rest of the program fail for the unlikely                // event that someone tries to compress an 16 x 16 pixel image                // which would of course be worse than pointless                BlockWidth[y] = (int) Math.ceil((double) compWidth[y]/8.0);                compHeight[y] = (((imageHeight%8 != 0) ? ((int) Math.ceil((double) imageHeight/8.0))*8: imageHeight)/MaxVsampFactor)*VsampFactor[y];                if (compHeight[y] != ((imageHeight/MaxVsampFactor)*VsampFactor[y])) {                        lastRowIsDummy[y] = true;                }                BlockHeight[y] = (int) Math.ceil((double) compHeight[y]/8.0);        }} else {        for (y = 0; y < NumberOfComponents; y++) {                compWidth[y] = ((		(imageWidth%8 != 0) ?		((int) Math.ceil((double) imageWidth/8.0))*8 :		imageWidth)		/MaxHsampFactor)*HsampFactor[y];                if (compWidth[y] != ((imageWidth/MaxHsampFactor)*HsampFactor[y])) {                        lastColumnIsDummy[y] = true;                }                // results in a multiple of 8 for compWidth                // this will make the rest of the program fail for the unlikely                // event that someone tries to compress an 16 x 16 pixel image                // which would of course be worse than pointless                BlockWidth[y] = (int) Math.ceil((double) compWidth[y]/8.0);                compHeight[y] = ((		(imageHeight%8 != 0) ?		((int) Math.ceil((double) imageHeight/8.0))*8:		imageHeight)		/MaxVsampFactor)*VsampFactor[y];                if (compHeight[y] != ((imageHeight/MaxVsampFactor)*VsampFactor[y])) {                        lastRowIsDummy[y] = true;                }                BlockHeight[y] = (int) Math.ceil((double) compHeight[y]/8.0);        }}        try    	{    	    if(grabber.grabPixels() != true)    	    {    		    try    		    {    		        throw new AWTException("Grabber returned false: " + grabber.getStatus());    		    }    		    catch (Exception e) {};            }    	}    	catch (InterruptedException e) {};        float Y[][] = new float[compHeight[0]][compWidth[0]];        float Cr1[][] = new float[compHeight[0]][compWidth[0]];        float Cb1[][] = new float[compHeight[0]][compWidth[0]];        float Cb2[][] = new float[compHeight[1]][compWidth[1]];        float Cr2[][] = new float[compHeight[2]][compWidth[2]];        int index = 0;        for (y = 0; y < imageHeight; ++y)    	{            for (x = 0; x < imageWidth; ++x)    	    {                r = ((values[index] >> 16) & 0xff);                g = ((values[index] >> 8) & 0xff);                b = (values[index] & 0xff);// The following three lines are a more correct color conversion but// the current conversion technique is sufficient and results in a higher// compression rate.//                Y[y][x] = 16 + (float)(0.8588*(0.299 * (float)r + 0.587 * (float)g + 0.114 * (float)b ));//                Cb1[y][x] = 128 + (float)(0.8784*(-0.16874 * (float)r - 0.33126 * (float)g + 0.5 * (float)b));//                Cr1[y][x] = 128 + (float)(0.8784*(0.5 * (float)r - 0.41869 * (float)g - 0.08131 * (float)b));                Y[y][x] = (float)((0.299 * (float)r + 0.587 * (float)g + 0.114 * (float)b));                Cb1[y][x] = 128 + (float)((-0.16874 * (float)r - 0.33126 * (float)g + 0.5 * (float)b));                Cr1[y][x] = 128 + (float)((0.5 * (float)r - 0.41869 * (float)g - 0.08131 * (float)b));                index++;    	    }    	}// Need a way to set the H and V sample factors before allowing downsampling.// For now (04/04/98) downsampling must be hard coded.// Until a better downsampler is implemented, this will not be done.// Downsampling is currently supported.  The downsampling method here// is a simple box filter.        Components[0] = Y;	if (false) {	//        Cb2 = DownSample(Cb1, 1);		Components[1] = Cb1;	//        Cr2 = DownSample(Cr1, 2);		Components[2] = Cr1;	} else {	        Cb2 = DownSample(Cb1, 1);		Components[1] = Cb2;	        Cr2 = DownSample(Cr1, 2);		Components[2] = Cr2;	}    }    float[][] DownSample(float[][] C, int comp)    {        int inrow, incol;        int outrow, outcol;        float output[][];        float temp;        int bias;        inrow = 0;        incol = 0;        output = new float[compHeight[comp]][compWidth[comp]];        for (outrow = 0; outrow < compHeight[comp]; outrow++) {                bias = 1;                for (outcol = 0; outcol < compWidth[comp]; outcol++) {//System.out.println("outcol="+outcol);			temp = C[inrow][incol++];	// 00			temp += C[inrow++][incol--];	// 01			temp += C[inrow][incol++];	// 10			temp += C[inrow--][incol++] + (float)bias; // 11 -> 02                        output[outrow][outcol] = temp/(float)4.0;                        bias ^= 3;                }                inrow += 2;                incol = 0;        }        return output;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -