src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java

Print this page
rev 9292 : 8033716: Fix raw and unchecked lint warnings in com.sun.imageio
Reviewed-by: darcy, prr


  90 
  91     /** An intermediate Raster holding compressor-friendly data */
  92     private WritableRaster raster = null;
  93 
  94     /**
  95      * Set to true if we are writing an image with an
  96      * indexed ColorModel
  97      */
  98     private boolean indexed = false;
  99     private IndexColorModel indexCM = null;
 100 
 101     private boolean convertTosRGB = false;  // Used by PhotoYCC only
 102     private WritableRaster converted = null;
 103 
 104     private boolean isAlphaPremultiplied = false;
 105     private ColorModel srcCM = null;
 106 
 107     /**
 108      * If there are thumbnails to be written, this is the list.
 109      */
 110     private List thumbnails = null;
 111 
 112     /**
 113      * If metadata should include an icc profile, store it here.
 114      */
 115     private ICC_Profile iccProfile = null;
 116 
 117     private int sourceXOffset = 0;
 118     private int sourceYOffset = 0;
 119     private int sourceWidth = 0;
 120     private int [] srcBands = null;
 121     private int sourceHeight = 0;
 122 
 123     /** Used when calling listeners */
 124     private int currentImage = 0;
 125 
 126     private ColorConvertOp convertOp = null;
 127 
 128     private JPEGQTable [] streamQTables = null;
 129     private JPEGHuffmanTable[] streamDCHuffmanTables = null;
 130     private JPEGHuffmanTable[] streamACHuffmanTables = null;


1377                 warningOccurred(input
1378                                 ? WARNING_IMAGE_METADATA_ADOBE_MISMATCH
1379                                 : WARNING_DEST_METADATA_ADOBE_MISMATCH);
1380                 if (rightTransform == JPEG.ADOBE_IMPOSSIBLE) {
1381                     ignoreAdobe = true;
1382                 } else {
1383                     newAdobeTransform = rightTransform;
1384                 }
1385             }
1386         }
1387     }
1388 
1389     /**
1390      * Collect all the scan info from the given metadata, and
1391      * organize it into the scan info array required by the
1392      * IJG libray.  It is much simpler to parse out this
1393      * data in Java and then just copy the data in C.
1394      */
1395     private int [] collectScans(JPEGMetadata metadata,
1396                                 SOFMarkerSegment sof) {
1397         List segments = new ArrayList();
1398         int SCAN_SIZE = 9;
1399         int MAX_COMPS_PER_SCAN = 4;
1400         for (Iterator iter = metadata.markerSequence.iterator();
1401              iter.hasNext();) {
1402             MarkerSegment seg = (MarkerSegment) iter.next();
1403             if (seg instanceof SOSMarkerSegment) {
1404                 segments.add(seg);
1405             }
1406         }
1407         int [] retval = null;
1408         numScans = 0;
1409         if (!segments.isEmpty()) {
1410             numScans = segments.size();
1411             retval = new int [numScans*SCAN_SIZE];
1412             int index = 0;
1413             for (int i = 0; i < numScans; i++) {
1414                 SOSMarkerSegment sos = (SOSMarkerSegment) segments.get(i);
1415                 retval[index++] = sos.componentSpecs.length; // num comps
1416                 for (int j = 0; j < MAX_COMPS_PER_SCAN; j++) {
1417                     if (j < sos.componentSpecs.length) {
1418                         int compSel = sos.componentSpecs[j].componentSelector;
1419                         for (int k = 0; k < sof.componentSpecs.length; k++) {
1420                             if (compSel == sof.componentSpecs[k].componentId) {
1421                                 retval[index++] = k;
1422                                 break; // out of for over sof comps
1423                             }
1424                         }
1425                     } else {
1426                         retval[index++] = 0;
1427                     }
1428                 }
1429                 retval[index++] = sos.startSpectralSelection;
1430                 retval[index++] = sos.endSpectralSelection;
1431                 retval[index++] = sos.approxHigh;
1432                 retval[index++] = sos.approxLow;
1433             }
1434         }
1435         return retval;
1436     }
1437 
1438     /**
1439      * Finds all DQT marker segments and returns all the q
1440      * tables as a single array of JPEGQTables.
1441      */
1442     private JPEGQTable [] collectQTablesFromMetadata
1443         (JPEGMetadata metadata) {
1444         ArrayList tables = new ArrayList();
1445         Iterator iter = metadata.markerSequence.iterator();
1446         while (iter.hasNext()) {
1447             MarkerSegment seg = (MarkerSegment) iter.next();
1448             if (seg instanceof DQTMarkerSegment) {
1449                 DQTMarkerSegment dqt =
1450                     (DQTMarkerSegment) seg;
1451                 tables.addAll(dqt.tables);
1452             }
1453         }
1454         JPEGQTable [] retval = null;
1455         if (tables.size() != 0) {
1456             retval = new JPEGQTable[tables.size()];
1457             for (int i = 0; i < retval.length; i++) {
1458                 retval[i] =
1459                     new JPEGQTable(((DQTMarkerSegment.Qtable)tables.get(i)).data);
1460             }
1461         }
1462         return retval;
1463     }
1464 
1465     /**
1466      * Finds all DHT marker segments and returns all the q
1467      * tables as a single array of JPEGQTables.  The metadata
1468      * must not be for a progressive image, or an exception
1469      * will be thrown when two Huffman tables with the same
1470      * table id are encountered.
1471      */
1472     private JPEGHuffmanTable[] collectHTablesFromMetadata
1473         (JPEGMetadata metadata, boolean wantDC) throws IIOException {
1474         ArrayList tables = new ArrayList();
1475         Iterator iter = metadata.markerSequence.iterator();
1476         while (iter.hasNext()) {
1477             MarkerSegment seg = (MarkerSegment) iter.next();
1478             if (seg instanceof DHTMarkerSegment) {
1479                 DHTMarkerSegment dht =
1480                     (DHTMarkerSegment) seg;
1481                 for (int i = 0; i < dht.tables.size(); i++) {
1482                     DHTMarkerSegment.Htable htable =
1483                         (DHTMarkerSegment.Htable) dht.tables.get(i);
1484                     if (htable.tableClass == (wantDC ? 0 : 1)) {
1485                         tables.add(htable);
1486                     }
1487                 }
1488             }
1489         }
1490         JPEGHuffmanTable [] retval = null;
1491         if (tables.size() != 0) {
1492             DHTMarkerSegment.Htable [] htables =
1493                 new DHTMarkerSegment.Htable[tables.size()];
1494             tables.toArray(htables);
1495             retval = new JPEGHuffmanTable[tables.size()];
1496             for (int i = 0; i < retval.length; i++) {
1497                 retval[i] = null;
1498                 for (int j = 0; j < tables.size(); j++) {
1499                     if (htables[j].tableID == i) {
1500                         if (retval[i] != null) {
1501                             throw new IIOException("Metadata has duplicate Htables!");
1502                         }
1503                         retval[i] = new JPEGHuffmanTable(htables[j].numCodes,


1645         }
1646         return retval;
1647     }
1648 
1649     private boolean isSubsampled(SOFMarkerSegment.ComponentSpec [] specs) {
1650         int hsamp0 = specs[0].HsamplingFactor;
1651         int vsamp0 = specs[0].VsamplingFactor;
1652         for (int i = 1; i < specs.length; i++) {
1653             if ((specs[i].HsamplingFactor != hsamp0) ||
1654                 (specs[i].HsamplingFactor != hsamp0))
1655                 return true;
1656         }
1657         return false;
1658     }
1659 
1660     ////////////// End of ColorSpace conversion
1661 
1662     ////////////// Native methods and callbacks
1663 
1664     /** Sets up static native structures. */
1665     private static native void initWriterIDs(Class qTableClass,
1666                                              Class huffClass);
1667 
1668     /** Sets up per-writer native structure and returns a pointer to it. */
1669     private native long initJPEGImageWriter();
1670 
1671     /** Sets up native structures for output stream */
1672     private native void setDest(long structPointer);
1673 
1674     /**
1675      * Returns <code>true</code> if the write was aborted.
1676      */
1677     private native boolean writeImage(long structPointer,
1678                                       byte [] data,
1679                                       int inCsType, int outCsType,
1680                                       int numBands,
1681                                       int [] bandSizes,
1682                                       int srcWidth,
1683                                       int destWidth, int destHeight,
1684                                       int stepX, int stepY,
1685                                       JPEGQTable [] qtables,
1686                                       boolean writeDQT,




  90 
  91     /** An intermediate Raster holding compressor-friendly data */
  92     private WritableRaster raster = null;
  93 
  94     /**
  95      * Set to true if we are writing an image with an
  96      * indexed ColorModel
  97      */
  98     private boolean indexed = false;
  99     private IndexColorModel indexCM = null;
 100 
 101     private boolean convertTosRGB = false;  // Used by PhotoYCC only
 102     private WritableRaster converted = null;
 103 
 104     private boolean isAlphaPremultiplied = false;
 105     private ColorModel srcCM = null;
 106 
 107     /**
 108      * If there are thumbnails to be written, this is the list.
 109      */
 110     private List<? extends BufferedImage> thumbnails = null;
 111 
 112     /**
 113      * If metadata should include an icc profile, store it here.
 114      */
 115     private ICC_Profile iccProfile = null;
 116 
 117     private int sourceXOffset = 0;
 118     private int sourceYOffset = 0;
 119     private int sourceWidth = 0;
 120     private int [] srcBands = null;
 121     private int sourceHeight = 0;
 122 
 123     /** Used when calling listeners */
 124     private int currentImage = 0;
 125 
 126     private ColorConvertOp convertOp = null;
 127 
 128     private JPEGQTable [] streamQTables = null;
 129     private JPEGHuffmanTable[] streamDCHuffmanTables = null;
 130     private JPEGHuffmanTable[] streamACHuffmanTables = null;


1377                 warningOccurred(input
1378                                 ? WARNING_IMAGE_METADATA_ADOBE_MISMATCH
1379                                 : WARNING_DEST_METADATA_ADOBE_MISMATCH);
1380                 if (rightTransform == JPEG.ADOBE_IMPOSSIBLE) {
1381                     ignoreAdobe = true;
1382                 } else {
1383                     newAdobeTransform = rightTransform;
1384                 }
1385             }
1386         }
1387     }
1388 
1389     /**
1390      * Collect all the scan info from the given metadata, and
1391      * organize it into the scan info array required by the
1392      * IJG libray.  It is much simpler to parse out this
1393      * data in Java and then just copy the data in C.
1394      */
1395     private int [] collectScans(JPEGMetadata metadata,
1396                                 SOFMarkerSegment sof) {
1397         List<SOSMarkerSegment> segments = new ArrayList<>();
1398         int SCAN_SIZE = 9;
1399         int MAX_COMPS_PER_SCAN = 4;
1400         for (Iterator<MarkerSegment> iter = metadata.markerSequence.iterator();
1401              iter.hasNext();) {
1402             MarkerSegment seg = iter.next();
1403             if (seg instanceof SOSMarkerSegment) {
1404                 segments.add((SOSMarkerSegment) seg);
1405             }
1406         }
1407         int [] retval = null;
1408         numScans = 0;
1409         if (!segments.isEmpty()) {
1410             numScans = segments.size();
1411             retval = new int [numScans*SCAN_SIZE];
1412             int index = 0;
1413             for (int i = 0; i < numScans; i++) {
1414                 SOSMarkerSegment sos = segments.get(i);
1415                 retval[index++] = sos.componentSpecs.length; // num comps
1416                 for (int j = 0; j < MAX_COMPS_PER_SCAN; j++) {
1417                     if (j < sos.componentSpecs.length) {
1418                         int compSel = sos.componentSpecs[j].componentSelector;
1419                         for (int k = 0; k < sof.componentSpecs.length; k++) {
1420                             if (compSel == sof.componentSpecs[k].componentId) {
1421                                 retval[index++] = k;
1422                                 break; // out of for over sof comps
1423                             }
1424                         }
1425                     } else {
1426                         retval[index++] = 0;
1427                     }
1428                 }
1429                 retval[index++] = sos.startSpectralSelection;
1430                 retval[index++] = sos.endSpectralSelection;
1431                 retval[index++] = sos.approxHigh;
1432                 retval[index++] = sos.approxLow;
1433             }
1434         }
1435         return retval;
1436     }
1437 
1438     /**
1439      * Finds all DQT marker segments and returns all the q
1440      * tables as a single array of JPEGQTables.
1441      */
1442     private JPEGQTable [] collectQTablesFromMetadata
1443         (JPEGMetadata metadata) {
1444         ArrayList<DQTMarkerSegment.Qtable> tables = new ArrayList<>();
1445         Iterator<MarkerSegment> iter = metadata.markerSequence.iterator();
1446         while (iter.hasNext()) {
1447             MarkerSegment seg = iter.next();
1448             if (seg instanceof DQTMarkerSegment) {
1449                 DQTMarkerSegment dqt =
1450                     (DQTMarkerSegment) seg;
1451                 tables.addAll(dqt.tables);
1452             }
1453         }
1454         JPEGQTable [] retval = null;
1455         if (tables.size() != 0) {
1456             retval = new JPEGQTable[tables.size()];
1457             for (int i = 0; i < retval.length; i++) {
1458                 retval[i] =
1459                     new JPEGQTable(tables.get(i).data);
1460             }
1461         }
1462         return retval;
1463     }
1464 
1465     /**
1466      * Finds all DHT marker segments and returns all the q
1467      * tables as a single array of JPEGQTables.  The metadata
1468      * must not be for a progressive image, or an exception
1469      * will be thrown when two Huffman tables with the same
1470      * table id are encountered.
1471      */
1472     private JPEGHuffmanTable[] collectHTablesFromMetadata
1473         (JPEGMetadata metadata, boolean wantDC) throws IIOException {
1474         ArrayList<DHTMarkerSegment.Htable> tables = new ArrayList<>();
1475         Iterator<MarkerSegment> iter = metadata.markerSequence.iterator();
1476         while (iter.hasNext()) {
1477             MarkerSegment seg = iter.next();
1478             if (seg instanceof DHTMarkerSegment) {
1479                 DHTMarkerSegment dht = (DHTMarkerSegment) seg;

1480                 for (int i = 0; i < dht.tables.size(); i++) {
1481                     DHTMarkerSegment.Htable htable = dht.tables.get(i);

1482                     if (htable.tableClass == (wantDC ? 0 : 1)) {
1483                         tables.add(htable);
1484                     }
1485                 }
1486             }
1487         }
1488         JPEGHuffmanTable [] retval = null;
1489         if (tables.size() != 0) {
1490             DHTMarkerSegment.Htable [] htables =
1491                 new DHTMarkerSegment.Htable[tables.size()];
1492             tables.toArray(htables);
1493             retval = new JPEGHuffmanTable[tables.size()];
1494             for (int i = 0; i < retval.length; i++) {
1495                 retval[i] = null;
1496                 for (int j = 0; j < tables.size(); j++) {
1497                     if (htables[j].tableID == i) {
1498                         if (retval[i] != null) {
1499                             throw new IIOException("Metadata has duplicate Htables!");
1500                         }
1501                         retval[i] = new JPEGHuffmanTable(htables[j].numCodes,


1643         }
1644         return retval;
1645     }
1646 
1647     private boolean isSubsampled(SOFMarkerSegment.ComponentSpec [] specs) {
1648         int hsamp0 = specs[0].HsamplingFactor;
1649         int vsamp0 = specs[0].VsamplingFactor;
1650         for (int i = 1; i < specs.length; i++) {
1651             if ((specs[i].HsamplingFactor != hsamp0) ||
1652                 (specs[i].HsamplingFactor != hsamp0))
1653                 return true;
1654         }
1655         return false;
1656     }
1657 
1658     ////////////// End of ColorSpace conversion
1659 
1660     ////////////// Native methods and callbacks
1661 
1662     /** Sets up static native structures. */
1663     private static native void initWriterIDs(Class<?> qTableClass,
1664                                              Class<?> huffClass);
1665 
1666     /** Sets up per-writer native structure and returns a pointer to it. */
1667     private native long initJPEGImageWriter();
1668 
1669     /** Sets up native structures for output stream */
1670     private native void setDest(long structPointer);
1671 
1672     /**
1673      * Returns <code>true</code> if the write was aborted.
1674      */
1675     private native boolean writeImage(long structPointer,
1676                                       byte [] data,
1677                                       int inCsType, int outCsType,
1678                                       int numBands,
1679                                       int [] bandSizes,
1680                                       int srcWidth,
1681                                       int destWidth, int destHeight,
1682                                       int stepX, int stepY,
1683                                       JPEGQTable [] qtables,
1684                                       boolean writeDQT,