OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [imageio/] [jpeg/] [JPEGDecoder.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* JPEGDecoder.java --
2
   Copyright (C)  2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.javax.imageio.jpeg;
39
 
40
import java.io.IOException;
41
import java.nio.ByteOrder;
42
 
43
import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
44
import javax.imageio.plugins.jpeg.JPEGQTable;
45
import javax.imageio.stream.ImageInputStream;
46
 
47
import java.util.ArrayList;
48
import java.util.Hashtable;
49
import java.awt.Point;
50
import java.awt.Transparency;
51
import java.awt.color.ColorSpace;
52
import java.awt.image.BufferedImage;
53
import java.awt.image.ComponentColorModel;
54
import java.awt.image.DataBuffer;
55
import java.awt.image.Raster;
56
import java.awt.image.WritableRaster;
57
 
58
public class JPEGDecoder
59
{
60
  byte majorVersion;
61
  byte minorVersion;
62
  byte units;
63
  short Xdensity;
64
  short Ydensity;
65
  byte Xthumbnail;
66
  byte Ythumbnail;
67
  byte[] thumbnail;
68
  BufferedImage image;
69
  int width;
70
  int height;
71
 
72
  byte marker;
73
 
74
  /**
75
   * This decoder expects JFIF 1.02 encoding.
76
   */
77
  public static final byte MAJOR_VERSION = (byte) 1;
78
  public static final byte MINOR_VERSION = (byte) 2;
79
 
80
  /**
81
   * The length of the JFIF field not including thumbnail data.
82
   */
83
  public static final short JFIF_FIXED_LENGTH = 16;
84
 
85
  /**
86
   * The length of the JFIF extension field not including extension
87
   * data.
88
   */
89
  public static final short JFXX_FIXED_LENGTH = 8;
90
 
91
  private JPEGImageInputStream jpegStream;
92
 
93
  ArrayList jpegFrames = new ArrayList();
94
 
95
  JPEGHuffmanTable[] dcTables = new JPEGHuffmanTable[4];
96
  JPEGHuffmanTable[] acTables = new JPEGHuffmanTable[4];
97
  JPEGQTable[] qTables = new JPEGQTable[4];
98
 
99
    public int getHeight()
100
    {
101
      return height;
102
    }
103
 
104
    public int getWidth()
105
    {
106
        return width;
107
    }
108
  public JPEGDecoder(ImageInputStream in)
109
    throws IOException, JPEGException
110
  {
111
    jpegStream = new JPEGImageInputStream(in);
112
    jpegStream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
113
 
114
    if (jpegStream.findNextMarker() != JPEGMarker.SOI)
115
      throw new JPEGException("Failed to find SOI marker.");
116
 
117
    if (jpegStream.findNextMarker() != JPEGMarker.APP0)
118
      throw new JPEGException("Failed to find APP0 marker.");
119
 
120
    int length = jpegStream.readShort();
121
    if (!(length >= JFIF_FIXED_LENGTH))
122
      throw new JPEGException("Failed to find JFIF field.");
123
 
124
    byte[] identifier = new byte[5];
125
    jpegStream.read(identifier);
126
    if (identifier[0] != JPEGMarker.JFIF_J
127
        || identifier[1] != JPEGMarker.JFIF_F
128
        || identifier[2] != JPEGMarker.JFIF_I
129
        || identifier[3] != JPEGMarker.JFIF_F
130
        || identifier[4] != JPEGMarker.X00)
131
      throw new JPEGException("Failed to read JFIF identifier.");
132
 
133
    majorVersion = jpegStream.readByte();
134
    minorVersion = jpegStream.readByte();
135
    if (majorVersion != MAJOR_VERSION
136
        || (majorVersion == MAJOR_VERSION
137
            && minorVersion < MINOR_VERSION))
138
      throw new JPEGException("Unsupported JFIF version.");
139
 
140
    units = jpegStream.readByte();
141
    if (units > (byte) 2)
142
      throw new JPEGException("Units field is out of range.");
143
 
144
    Xdensity = jpegStream.readShort();
145
    Ydensity = jpegStream.readShort();
146
    Xthumbnail = jpegStream.readByte();
147
    Ythumbnail = jpegStream.readByte();
148
 
149
    // 3 * for RGB data
150
    int thumbnailLength = 3 * Xthumbnail * Ythumbnail;
151
    if (length > JFIF_FIXED_LENGTH
152
        && thumbnailLength != length - JFIF_FIXED_LENGTH)
153
      throw new JPEGException("Invalid length, Xthumbnail"
154
                              + " or Ythumbnail field.");
155
 
156
    if (thumbnailLength > 0)
157
      {
158
        thumbnail = new byte[thumbnailLength];
159
        if (jpegStream.read(thumbnail) != thumbnailLength)
160
          throw new IOException("Failed to read thumbnail.");
161
      }
162
  }
163
 
164
  public void decode()
165
    throws IOException
166
  {
167
    System.out.println ("DECODE!!!");
168
    // The frames in this jpeg are loaded into a list. There is
169
    // usually just one frame except in heirarchial progression where
170
    // there are multiple frames.
171
    JPEGFrame frame = null;
172
 
173
    // The restart interval defines how many MCU's we should have
174
    // between the 8-modulo restart marker. The restart markers allow
175
    // us to tell whether or not our decoding process is working
176
    // correctly, also if there is corruption in the image we can
177
    // recover with these restart intervals. (See RSTm DRI).
178
    int resetInterval = 0;
179
 
180
    // The JPEGDecoder constructor parses the JFIF field.  At this
181
    // point jpegStream points to the first byte after the JFIF field.
182
 
183
    // Find the first marker after the JFIF field.
184
    byte marker = jpegStream.findNextMarker();
185
 
186
    // Check for a JFIF extension field directly following the JFIF
187
    // header and advance the current marker to the next marker in the
188
    // stream, if necessary.
189
    decodeJFIFExtension();
190
 
191
    // Loop through until there are no more markers to read in, at
192
    // that point everything is loaded into the jpegFrames array and
193
    // can be processed.
194
    while (true)
195
      {
196
        switch (marker)
197
          {
198
            // APPn Application Reserved Information - Just throw this
199
            // information away because we wont be using it.
200
          case JPEGMarker.APP0:
201
          case JPEGMarker.APP1:
202
          case JPEGMarker.APP2:
203
          case JPEGMarker.APP3:
204
          case JPEGMarker.APP4:
205
          case JPEGMarker.APP5:
206
          case JPEGMarker.APP6:
207
          case JPEGMarker.APP7:
208
          case JPEGMarker.APP8:
209
          case JPEGMarker.APP9:
210
          case JPEGMarker.APP10:
211
          case JPEGMarker.APP11:
212
          case JPEGMarker.APP12:
213
          case JPEGMarker.APP13:
214
          case JPEGMarker.APP14:
215
          case JPEGMarker.APP15:
216
            jpegStream.skipBytes(jpegStream.readShort() - 2);
217
            break;
218
 
219
          case JPEGMarker.SOF0:
220
            // SOFn Start of Frame Marker, Baseline DCT - This is the start
221
            // of the frame header that defines certain variables that will
222
            // be carried out through the rest of the encoding. Multiple
223
            // frames are used in a heirarchiel system, however most JPEG's
224
            // only contain a single frame.
225
            jpegFrames.add(new JPEGFrame());
226
            frame = (JPEGFrame) jpegFrames.get(jpegFrames.size() - 1);
227
            // Skip the frame length.
228
            jpegStream.readShort();
229
            // Bits percision, either 8 or 12.
230
            frame.setPrecision(jpegStream.readByte());
231
            // Scan lines = to the height of the frame.
232
            frame.setScanLines(jpegStream.readShort());
233
            // Scan samples per line = to the width of the frame.
234
            frame.setSamplesPerLine(jpegStream.readShort());
235
            // Number of Color Components (or channels).
236
            frame.setComponentCount(jpegStream.readByte());
237
 
238
            // Set the color mode for this frame, so far only 2 color
239
            // modes are supported.
240
            if (frame.getComponentCount() == 1)
241
              frame.setColorMode(JPEGFrame.JPEG_COLOR_GRAY);
242
            else
243
              frame.setColorMode(JPEGFrame.JPEG_COLOR_YCbCr);
244
            // Add all of the necessary components to the frame.
245
            for (int i = 0; i < frame.getComponentCount(); i++)
246
              frame.addComponent(jpegStream.readByte(), jpegStream.readByte(),
247
                                 jpegStream.readByte());
248
            break;
249
 
250
          case JPEGMarker.SOF2:
251
            jpegFrames.add(new JPEGFrame());
252
            frame = (JPEGFrame) jpegFrames.get(jpegFrames.size() - 1);
253
            // Skip the frame length.
254
            jpegStream.readShort();
255
            // Bits percision, either 8 or 12.
256
            frame.setPrecision(jpegStream.readByte());
257
            // Scan lines = to the height of the frame.
258
            frame.setScanLines(jpegStream.readShort());
259
            // Scan samples per line = to the width of the frame.
260
            frame.setSamplesPerLine(jpegStream.readShort());
261
            // Number of Color Components (or channels).
262
            frame.setComponentCount(jpegStream.readByte());
263
 
264
            // Set the color mode for this frame, so far only 2 color
265
            // modes are supported.
266
            if (frame.getComponentCount() == 1)
267
              frame.setColorMode(JPEGFrame.JPEG_COLOR_GRAY);
268
            else
269
              frame.setColorMode(JPEGFrame.JPEG_COLOR_YCbCr);
270
 
271
            // Add all of the necessary components to the frame.
272
            for (int i = 0; i < frame.getComponentCount(); i++)
273
              frame.addComponent(jpegStream.readByte(), jpegStream.readByte(),
274
                                 jpegStream.readByte());
275
            break;
276
 
277
          case JPEGMarker.DHT:
278
            // DHT non-SOF Marker - Huffman Table is required for decoding
279
            // the JPEG stream, when we receive a marker we load in first
280
            // the table length (16 bits), the table class (4 bits), table
281
            // identifier (4 bits), then we load in 16 bytes and each byte
282
            // represents the count of bytes to load in for each of the 16
283
            // bytes. We load this into an array to use later and move on 4
284
            // huffman tables can only be used in an image.
285
            int huffmanLength = (jpegStream.readShort() - 2);
286
 
287
            // Keep looping until we are out of length.
288
            int index = huffmanLength;
289
 
290
            // Multiple tables may be defined within a DHT marker. This
291
            // will keep reading until there are no tables left, most
292
            // of the time there are just one tables.
293
            while (index > 0)
294
              {
295
                // Read the identifier information and class
296
                // information about the Huffman table, then read the
297
                // 16 byte codelength in and read in the Huffman values
298
                // and put it into table info.
299
                byte huffmanInfo = jpegStream.readByte();
300
                byte tableClass = (byte) (huffmanInfo >> 4);
301
                byte huffmanIndex = (byte) (huffmanInfo & 0x0f);
302
                short[] codeLength = new short[16];
303
                jpegStream.readFully(codeLength, 0, codeLength.length);
304
                int huffmanValueLen = 0;
305
                for (int i = 0; i < 16; i++)
306
                  huffmanValueLen += codeLength[i];
307
                index -= (huffmanValueLen + 17);
308
                short[] huffmanVal = new short[huffmanValueLen];
309
                for (int i = 0; i < huffmanVal.length; i++)
310
                  huffmanVal[i] = jpegStream.readByte();
311
                // Assign DC Huffman Table.
312
                if (tableClass == HuffmanTable.JPEG_DC_TABLE)
313
                  dcTables[(int) huffmanIndex] = new JPEGHuffmanTable(codeLength,
314
                                                                      huffmanVal);
315
                // Assign AC Huffman Table.
316
                else if (tableClass == HuffmanTable.JPEG_AC_TABLE)
317
                  acTables[(int) huffmanIndex] = new JPEGHuffmanTable(codeLength,
318
                                                                      huffmanVal);
319
              }
320
            break;
321
          case JPEGMarker.DQT:
322
            // DQT non-SOF Marker - This defines the quantization
323
            // coeffecients, this allows us to figure out the quality of
324
            // compression and unencode the data. The data is loaded and
325
            // then stored in to an array.
326
            short quantizationLength = (short) (jpegStream.readShort() - 2);
327
            for (int j = 0; j < quantizationLength / 65; j++)
328
              {
329
                byte quantSpecs = jpegStream.readByte();
330
                int[] quantData = new int[64];
331
                if ((byte) (quantSpecs >> 4) == 0)
332
                  // Precision 8 bit.
333
                  {
334
                    for (int i = 0; i < 64; i++)
335
                      quantData[i] = jpegStream.readByte();
336
 
337
                  }
338
                else if ((byte) (quantSpecs >> 4) == 1)
339
                  // Precision 16 bit.
340
                  {
341
                    for (int i = 0; i < 64; i++)
342
                      quantData[i] = jpegStream.readShort();
343
                  }
344
                qTables[(int) (quantSpecs & 0x0f)] = new JPEGQTable (quantData);
345
              }
346
            break;
347
          case JPEGMarker.SOS:
348
            // SOS non-SOF Marker - Start Of Scan Marker, this is where the
349
            // actual data is stored in a interlaced or non-interlaced with
350
            // from 1-4 components of color data, if three components most
351
            // likely a YCrCb model, this is a fairly complex process.
352
 
353
            // Read in the scan length.
354
            jpegStream.readShort();
355
            // Number of components in the scan.
356
            byte numberOfComponents = jpegStream.readByte();
357
            byte[] componentSelector = new byte[numberOfComponents];
358
            for (int i = 0; i < numberOfComponents; i++)
359
              {
360
                // Component ID, packed byte containing the Id for the
361
                // AC table and DC table.
362
                byte componentID = jpegStream.readByte();
363
                byte tableInfo = jpegStream.readByte();
364
                frame.setHuffmanTables(componentID,
365
                                       acTables[(byte) (tableInfo >> 4)],
366
                                       dcTables[(byte) (tableInfo & 0x0f)]);
367
                componentSelector[i] = componentID;
368
              }
369
            byte startSpectralSelection = jpegStream.readByte();
370
            byte endSpectralSelection = jpegStream.readByte();
371
            byte successiveApproximation = jpegStream.readByte();
372
 
373
            int mcuIndex = 0;
374
            int mcuTotalIndex = 0;
375
            // This loops through until a MarkerTagFound exception is
376
            // found, if the marker tag is a RST (Restart Marker) it
377
            // simply skips it and moves on this system does not handle
378
            // corrupt data streams very well, it could be improved by
379
            // handling misplaced restart markers.
380
            while (true)
381
              {
382
                try
383
                  {
384
                    // Loop though capturing MCU, instruct each
385
                    // component to read in its necessary count, for
386
                    // scaling factors the components automatically
387
                    // read in how much they need
388
                    for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
389
                      {
390
                        JPEGComponent comp = frame.components.getComponentByID(componentSelector[compIndex]);
391
                        comp.readComponentMCU(jpegStream);
392
                      }
393
                    mcuIndex++;
394
                    mcuTotalIndex++;
395
                  }
396
                // We've found a marker, see if the marker is a restart
397
                // marker or just the next marker in the stream. If
398
                // it's the next marker in the stream break out of the
399
                // while loop, if it's just a restart marker skip it
400
                catch (JPEGMarkerFoundException bse)
401
                  {
402
                    // Handle JPEG Restart Markers, this is where the
403
                    // count of MCU's per interval is compared with
404
                    // the count actually obtained, if it's short then
405
                    // pad on some MCU's ONLY for components that are
406
                    // greater than one. Also restart the DC prediction
407
                    // to zero.
408
                    if (marker == JPEGMarker.RST0
409
                        || marker == JPEGMarker.RST1
410
                        || marker == JPEGMarker.RST2
411
                        || marker == JPEGMarker.RST3
412
                        || marker == JPEGMarker.RST4
413
                        || marker == JPEGMarker.RST5
414
                        || marker == JPEGMarker.RST6
415
                        || marker == JPEGMarker.RST7)
416
                      {
417
                        for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
418
                          {
419
                            JPEGComponent comp = frame.components.getComponentByID(componentSelector[compIndex]);
420
                            if (compIndex > 1)
421
                              comp.padMCU(mcuTotalIndex, resetInterval - mcuIndex);
422
                            comp.resetInterval();
423
                          }
424
                        mcuTotalIndex += (resetInterval - mcuIndex);
425
                        mcuIndex = 0;
426
                      }
427
                    else
428
                      {
429
                        // We're at the end of our scan, exit out.
430
                        break;
431
                      }
432
                  }
433
              }
434
            break;
435
          case JPEGMarker.DRI:
436
            // DRI - This defines the restart interval, if we have a
437
            // restart interval when we reach our restart modulo calculate
438
            // whether the count of MCU's specified in the restart
439
            // interval have been reached, if they havent then pad with
440
            // whatever MCU was last used, this is supposed to be a form of
441
            // error recovery but it turns out that some JPEG encoders
442
            // purposely cause missing MCU's on repeating MCU's to compress
443
            // data even more (even though it adds an extra layer of
444
            // complexity.. But since when is JPEG easy?
445
            jpegStream.skipBytes(2);
446
            resetInterval = jpegStream.readShort();
447
            break;
448
          case JPEGMarker.COM:
449
            // COM - This is a comment that was inserted into the JPEG, we
450
            // simply skip over the comment because it's really of no
451
            // importance, usually contains a verbal description of the
452
            // application or author who created the JPEG.
453
            jpegStream.skipBytes(jpegStream.readShort() - 2);
454
            break;
455
          case JPEGMarker.DNL:
456
            // DNL - This sets the height of the image. This is the Define
457
            // Number Lines for the image, I'm not sure exactly why we need
458
            // this but, whatever we'll abide.
459
            frame.setScanLines(jpegStream.readShort());
460
            break;
461
          case JPEGMarker.EOI:
462
            // EOI - End of Image, this processes the frames and turns the
463
            // frames into a buffered image.
464
 
465
            if (jpegFrames.size() == 0)
466
              {
467
                return;
468
              }
469
            else if (jpegFrames.size() == 1)
470
              {
471
                // Only one frame, JPEG Non-Heirarchial Frame.
472
 
473
                DCT myDCT = new DCT();
474
                WritableRaster raster =
475
                  Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
476
                                                 frame.width,
477
                                                 frame.height,
478
                                                 frame.getComponentCount(),
479
                                                 new Point(0, 0));
480
 
481
                // Unencode the data.
482
                for (int i = 0; i < frame.getComponentCount(); i++)
483
                  {
484
                    JPEGComponent comp = frame.components.get(i);
485
                    comp.setQuantizationTable(qTables[comp.quant_id].getTable());
486
                    comp.quantitizeData();
487
                    comp.idctData(myDCT);
488
                  }
489
                // Scale the image and write the data to the raster.
490
                for (int i = 0; i < frame.getComponentCount(); i++)
491
                  {
492
                    JPEGComponent comp = frame.components.get(i);
493
                    comp.scaleByFactors();
494
                    comp.writeData(raster, i);
495
                    // Ensure garbage collection.
496
                    comp = null;
497
                  }
498
                // Grayscale Color Image (1 Component).
499
                if (frame.getComponentCount() == 1)
500
                  {
501
                    ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
502
                    ComponentColorModel ccm =
503
                      new ComponentColorModel(cs, false, false,
504
                                              Transparency.OPAQUE,
505
                                              DataBuffer.TYPE_BYTE);
506
                    image = new BufferedImage(ccm, raster, false,
507
                                              new Hashtable());
508
                  }
509
                // YCbCr Color Image (3 Components).
510
                else if (frame.getComponentCount() == 3)
511
                  {
512
                    ComponentColorModel ccm =
513
                      new ComponentColorModel(new YCbCr_ColorSpace(), false,
514
                                              false, Transparency.OPAQUE,
515
                                              DataBuffer.TYPE_BYTE);
516
                    image = new BufferedImage(ccm, raster, false,
517
                                              new Hashtable());
518
                  }
519
                // Possibly CMYK or RGBA ?
520
                else
521
                  {
522
                    throw new JPEGException("Unsupported Color Mode: 4 "
523
                                            + "Component Color Mode found.");
524
                  }
525
                height = frame.height;
526
                width = frame.width;
527
              }
528
            else
529
              {
530
                //JPEG Heirarchial Frame (progressive or baseline).
531
                throw new JPEGException("Unsupported Codec Type:"
532
                                        + " Hierarchial JPEG");
533
              }
534
            break;
535
          case JPEGMarker.SOF1:
536
            // ERROR - If we encounter any of the following marker codes
537
            // error out with a codec exception, progressive, heirarchial,
538
            // differential, arithmetic, lossless JPEG's are not supported.
539
            // This is where enhancements can be made for future versions.
540
            // Thankfully 99% of all JPEG's are baseline DCT.
541
            throw new JPEGException("Unsupported Codec Type: Extended "
542
                                    + "Sequential DCT JPEG's Not-Supported");
543
            //case JPEGMarker.SOF2:
544
            //  throw new JPEGException("Unsupported Codec Type: Progressive DCT JPEG's Not-Supported");
545
          case JPEGMarker.SOF3:
546
            throw new JPEGException("Unsupported Codec Type:"
547
                                    + " Lossless (sequential)");
548
          case JPEGMarker.SOF5:
549
            throw new JPEGException("Unsupported Codec Type:"
550
                                    + " Differential sequential DCT");
551
          case JPEGMarker.SOF6:
552
            throw new JPEGException("Unsupported Codec Type:"
553
                                    + " Differential progressive DCT");
554
          case JPEGMarker.SOF7:
555
            throw new JPEGException("Unsupported Codec Type:"
556
                                    + " Differential lossless");
557
          case JPEGMarker.SOF9:
558
          case JPEGMarker.SOF10:
559
          case JPEGMarker.SOF11:
560
          case JPEGMarker.SOF13:
561
          case JPEGMarker.SOF14:
562
          case JPEGMarker.SOF15:
563
            throw new JPEGException("Unsupported Codec Type:"
564
                                    + " Arithmetic Coding Frame");
565
          default:
566
            // Unknown marker found, ignore it.
567
          }
568
        marker = jpegStream.findNextMarker();
569
      }
570
  }
571
 
572
  // If the current marker is APP0, tries to decode a JFIF extension
573
  // and advances the current marker to the next marker in the stream.
574
  private void decodeJFIFExtension() throws IOException
575
  {
576
    if (marker == JPEGMarker.APP0)
577
      {
578
        int length = jpegStream.readShort();
579
 
580
        if (length >= JFXX_FIXED_LENGTH)
581
          {
582
            byte[] identifier = new byte[5];
583
            jpegStream.read(identifier);
584
            if (identifier[0] != JPEGMarker.JFIF_J
585
                || identifier[1] != JPEGMarker.JFIF_F
586
                || identifier[2] != JPEGMarker.JFIF_X
587
                || identifier[3] != JPEGMarker.JFIF_X
588
                || identifier[4] != JPEGMarker.X00)
589
              // Not a JFXX field.  Ignore it and continue.
590
              jpegStream.skipBytes(length - 7);
591
            else
592
              {
593
                byte extension_code = jpegStream.readByte();
594
 
595
                switch (extension_code)
596
                  {
597
                  case JPEGMarker.JFXX_JPEG:
598
                    // FIXME: add support for JFIF Extension:
599
                    // Thumbnail coded using JPEG.
600
                    jpegStream.skipBytes(length - 8);
601
                  case JPEGMarker.JFXX_ONE_BPP:
602
                    // FIXME: add support for JFIF Extension:
603
                    // Thumbnail stored using 1 byte/pixel.
604
                    jpegStream.skipBytes(length - 8);
605
                  case JPEGMarker.JFXX_THREE_BPP:
606
                    // FIXME: add support for JFIF Extension:
607
                    // Thumbnail stored using 3 bytes/pixel.
608
                    jpegStream.skipBytes(length - 8);
609
                  }
610
              }
611
          }
612
        else
613
          {
614
            // Unknown APP0 marker.  Ignore it and continue.
615
            jpegStream.skipBytes(length - 2);
616
          }
617
        marker = jpegStream.findNextMarker();
618
      }
619
  }
620
 
621
  public BufferedImage getImage()
622
  {
623
    return image;
624
  }
625
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.