Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/obrador/JpegInfo.java


1   /*
2    * JpegInfo - Given an image, sets default information about it and divides
3    * it into its constituant components, downsizing those that need to be.
4    */
5   package com.obrador;
6   
7   import java.awt.AWTException;
8   import java.awt.Image;
9   import java.awt.image.PixelGrabber;
10  
11  
12  class JpegInfo
13  {
14      //~ Instance fields ////////////////////////////////////////////////////////
15  
16      public Image imageobj;
17      public int[] ACtableNumber = {0, 1, 1};
18      public int[] BlockHeight;
19      public int[] BlockWidth;
20      public int[] CompID = {1, 2, 3};
21      public Object[] Components;
22      public int[] DCtableNumber = {0, 1, 1};
23      public int[] HsampFactor = {1, 1, 1};
24      public int[] QtableNumber = {0, 1, 1};
25      public int[] VsampFactor = {1, 1, 1};
26      public int[] compHeight;
27      public int[] compWidth;
28      public boolean[] lastColumnIsDummy = {false, false, false};
29      public boolean[] lastRowIsDummy = {false, false, false};
30      public int Ah = 0;
31      public int Al = 0;
32      public int MaxHsampFactor;
33      public int MaxVsampFactor;
34      public int NumberOfComponents = 3;
35  
36      // the following are set as the default
37      public int Precision = 8;
38      public int Se = 63;
39      public int Ss = 0;
40      public int imageHeight;
41      public int imageWidth;
42      String Comment;
43  
44      //~ Constructors ///////////////////////////////////////////////////////////
45  
46      public JpegInfo(Image image)
47      {
48          Components = new Object[NumberOfComponents];
49          compWidth = new int[NumberOfComponents];
50          compHeight = new int[NumberOfComponents];
51          BlockWidth = new int[NumberOfComponents];
52          BlockHeight = new int[NumberOfComponents];
53          imageobj = image;
54          imageWidth = image.getWidth(null);
55          imageHeight = image.getHeight(null);
56          Comment = "JPEG Encoder Copyright 1998, James R. Weeks and BioElectroMech.  ";
57          getYCCArray();
58      }
59  
60      //~ Methods ////////////////////////////////////////////////////////////////
61  
62      public void setComment(String comment)
63      {
64          Comment.concat(comment);
65      }
66  
67      public String getComment()
68      {
69          return Comment;
70      }
71  
72      float[][] DownSample(float[][] C, int comp)
73      {
74          int inrow;
75          int incol;
76          int outrow;
77          int outcol;
78          float[][] output;
79          int temp;
80          int bias;
81          inrow = 0;
82          incol = 0;
83          output = new float[compHeight[comp]][compWidth[comp]];
84  
85          for (outrow = 0; outrow < compHeight[comp]; outrow++)
86          {
87              bias = 1;
88  
89              for (outcol = 0; outcol < compWidth[comp]; outcol++)
90              {
91                  output[outrow][outcol] = (C[inrow][incol++] +
92                      C[inrow++][incol--] + C[inrow][incol++] +
93                      C[inrow--][incol++] + (float) bias) / (float) 4.0;
94                  bias ^= 3;
95              }
96  
97              inrow += 2;
98              incol = 0;
99          }
100 
101         return output;
102     }
103 
104     /*
105      * This method creates and fills three arrays, Y, Cb, and Cr using the
106      * input image.
107      */
108     private void getYCCArray()
109     {
110         int[] values = new int[imageWidth * imageHeight];
111         int r;
112         int g;
113         int b;
114         int y;
115         int x;
116 
117         // In order to minimize the chance that grabPixels will throw an exception
118         // it may be necessary to grab some pixels every few scanlines and process
119         // those before going for more.  The time expense may be prohibitive.
120         // However, for a situation where memory overhead is a concern, this may be
121         // the only choice.
122         PixelGrabber grabber = new PixelGrabber(imageobj.getSource(), 0, 0,
123                 imageWidth, imageHeight, values, 0, imageWidth);
124         MaxHsampFactor = 1;
125         MaxVsampFactor = 1;
126 
127         for (y = 0; y < NumberOfComponents; y++)
128         {
129             MaxHsampFactor = Math.max(MaxHsampFactor, HsampFactor[y]);
130             MaxVsampFactor = Math.max(MaxVsampFactor, VsampFactor[y]);
131         }
132 
133         for (y = 0; y < NumberOfComponents; y++)
134         {
135             compWidth[y] = ((((imageWidth % 8) != 0)
136                 ? (((int) Math.ceil((double) imageWidth / 8.0)) * 8) : imageWidth) / MaxHsampFactor) * HsampFactor[y];
137 
138             if (compWidth[y] != ((imageWidth / MaxHsampFactor) * HsampFactor[y]))
139             {
140                 lastColumnIsDummy[y] = true;
141             }
142 
143             // results in a multiple of 8 for compWidth
144             // this will make the rest of the program fail for the unlikely
145             // event that someone tries to compress an 16 x 16 pixel image
146             // which would of course be worse than pointless
147             BlockWidth[y] = (int) Math.ceil((double) compWidth[y] / 8.0);
148             compHeight[y] = ((((imageHeight % 8) != 0)
149                 ? (((int) Math.ceil((double) imageHeight / 8.0)) * 8)
150                 : imageHeight) / MaxVsampFactor) * VsampFactor[y];
151 
152             if (compHeight[y] != ((imageHeight / MaxVsampFactor) * VsampFactor[y]))
153             {
154                 lastRowIsDummy[y] = true;
155             }
156 
157             BlockHeight[y] = (int) Math.ceil((double) compHeight[y] / 8.0);
158         }
159 
160         try
161         {
162             if (grabber.grabPixels() != true)
163             {
164                 try
165                 {
166                     throw new AWTException("Grabber returned false: " +
167                         grabber.status());
168                 }
169                  catch (Exception e)
170                 {
171                 }
172 
173                 ;
174             }
175         }
176          catch (InterruptedException e)
177         {
178         }
179 
180         ;
181 
182         float[][] Y = new float[compHeight[0]][compWidth[0]];
183         float[][] Cr1 = new float[compHeight[0]][compWidth[0]];
184         float[][] Cb1 = new float[compHeight[0]][compWidth[0]];
185         float[][] Cb2 = new float[compHeight[1]][compWidth[1]];
186         float[][] Cr2 = new float[compHeight[2]][compWidth[2]];
187         int index = 0;
188 
189         for (y = 0; y < imageHeight; ++y)
190         {
191             for (x = 0; x < imageWidth; ++x)
192             {
193                 r = ((values[index] >> 16) & 0xff);
194                 g = ((values[index] >> 8) & 0xff);
195                 b = (values[index] & 0xff);
196 
197                 // The following three lines are a more correct color conversion but
198                 // the current conversion technique is sufficient and results in a higher
199                 // compression rate.
200                 //                Y[y][x] = 16 + (float)(0.8588*(0.299 * (float)r + 0.587 * (float)g + 0.114 * (float)b ));
201                 //                Cb1[y][x] = 128 + (float)(0.8784*(-0.16874 * (float)r - 0.33126 * (float)g + 0.5 * (float)b));
202                 //                Cr1[y][x] = 128 + (float)(0.8784*(0.5 * (float)r - 0.41869 * (float)g - 0.08131 * (float)b));
203                 Y[y][x] = (float) (((0.299 * (float) r) + (0.587 * (float) g) +
204                     (0.114 * (float) b)));
205                 Cb1[y][x] = 128 +
206                     (float) (((-0.16874 * (float) r) - (0.33126 * (float) g) +
207                     (0.5 * (float) b)));
208                 Cr1[y][x] = 128 +
209                     (float) (((0.5 * (float) r) - (0.41869 * (float) g) -
210                     (0.08131 * (float) b)));
211                 index++;
212             }
213         }
214 
215         // Need a way to set the H and V sample factors before allowing downsampling.
216         // For now (04/04/98) downsampling must be hard coded.
217         // Until a better downsampler is implemented, this will not be done.
218         // Downsampling is currently supported.  The downsampling method here
219         // is a simple box filter.
220         Components[0] = Y;
221 
222         //        Cb2 = DownSample(Cb1, 1);
223         Components[1] = Cb1;
224 
225         //        Cr2 = DownSample(Cr1, 2);
226         Components[2] = Cr1;
227     }
228 }
229 ///////////////////////////////////////////////////////////////////////////////
230 //  END OF FILE.
231 ///////////////////////////////////////////////////////////////////////////////