jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java
changeset 16899 666a37b19844
parent 14884 74d1acdb7ee4
child 16900 5e0400ee2917
equal deleted inserted replaced
15973:ea0278a3c432 16899:666a37b19844
    97     int height;
    97     int height;
    98     int nextRowOffset;
    98     int nextRowOffset;
    99     int offset;
    99     int offset;
   100 
   100 
   101     Object dataArray;
   101     Object dataArray;
   102     private LCMSImageLayout(int np, int pixelType, int pixelSize) {
   102     private int dataArrayLength; /* in bytes */
       
   103 
       
   104     private LCMSImageLayout(int np, int pixelType, int pixelSize)
       
   105             throws ImageLayoutException
       
   106     {
   103         this.pixelType = pixelType;
   107         this.pixelType = pixelType;
   104         width = np;
   108         width = np;
   105         height = 1;
   109         height = 1;
   106         nextRowOffset = np*pixelSize;
   110         nextRowOffset = safeMult(pixelSize, np);
   107         offset = 0;
   111         offset = 0;
   108     }
   112     }
   109 
   113 
   110     private LCMSImageLayout(int width, int height, int pixelType,
   114     private LCMSImageLayout(int width, int height, int pixelType,
   111                             int pixelSize) {
   115                             int pixelSize)
       
   116             throws ImageLayoutException
       
   117     {
   112         this.pixelType = pixelType;
   118         this.pixelType = pixelType;
   113         this.width = width;
   119         this.width = width;
   114         this.height = height;
   120         this.height = height;
   115         nextRowOffset = width*pixelSize;
   121         nextRowOffset = safeMult(pixelSize, width);
   116         offset = 0;
   122         offset = 0;
   117     }
   123     }
   118 
   124 
   119 
   125 
   120     public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) {
   126     public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize)
       
   127             throws ImageLayoutException
       
   128     {
   121         this(np, pixelType, pixelSize);
   129         this(np, pixelType, pixelSize);
   122         dataType = DT_BYTE;
   130         dataType = DT_BYTE;
   123         dataArray = data;
   131         dataArray = data;
   124     }
   132         dataArrayLength = data.length;
   125 
   133 
   126     public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) {
   134         verify();
       
   135     }
       
   136 
       
   137     public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize)
       
   138             throws ImageLayoutException
       
   139     {
   127         this(np, pixelType, pixelSize);
   140         this(np, pixelType, pixelSize);
   128         dataType = DT_SHORT;
   141         dataType = DT_SHORT;
   129         dataArray = data;
   142         dataArray = data;
   130     }
   143         dataArrayLength = 2 * data.length;
   131 
   144 
   132     public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) {
   145         verify();
       
   146     }
       
   147 
       
   148     public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize)
       
   149             throws ImageLayoutException
       
   150     {
   133         this(np, pixelType, pixelSize);
   151         this(np, pixelType, pixelSize);
   134         dataType = DT_INT;
   152         dataType = DT_INT;
   135         dataArray = data;
   153         dataArray = data;
       
   154         dataArrayLength = 4 * data.length;
       
   155 
       
   156         verify();
   136     }
   157     }
   137 
   158 
   138     public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
   159     public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
       
   160             throws ImageLayoutException
   139     {
   161     {
   140         this(np, pixelType, pixelSize);
   162         this(np, pixelType, pixelSize);
   141         dataType = DT_DOUBLE;
   163         dataType = DT_DOUBLE;
   142         dataArray = data;
   164         dataArray = data;
   143     }
   165         dataArrayLength = 8 * data.length;
   144 
   166 
   145     public LCMSImageLayout(BufferedImage image) {
   167         verify();
       
   168     }
       
   169 
       
   170     public LCMSImageLayout(BufferedImage image) throws ImageLayoutException {
   146         ShortComponentRaster shortRaster;
   171         ShortComponentRaster shortRaster;
   147         IntegerComponentRaster intRaster;
   172         IntegerComponentRaster intRaster;
   148         ByteComponentRaster byteRaster;
   173         ByteComponentRaster byteRaster;
   149         switch (image.getType()) {
   174         switch (image.getType()) {
   150             case BufferedImage.TYPE_INT_RGB:
   175             case BufferedImage.TYPE_INT_RGB:
   184         switch (image.getType()) {
   209         switch (image.getType()) {
   185             case BufferedImage.TYPE_INT_RGB:
   210             case BufferedImage.TYPE_INT_RGB:
   186             case BufferedImage.TYPE_INT_ARGB:
   211             case BufferedImage.TYPE_INT_ARGB:
   187             case BufferedImage.TYPE_INT_BGR:
   212             case BufferedImage.TYPE_INT_BGR:
   188                 intRaster = (IntegerComponentRaster)image.getRaster();
   213                 intRaster = (IntegerComponentRaster)image.getRaster();
   189                 nextRowOffset = intRaster.getScanlineStride()*4;
   214 
   190                 offset = intRaster.getDataOffset(0)*4;
   215                 nextRowOffset = safeMult(4, intRaster.getScanlineStride());
       
   216 
       
   217                 offset = safeMult(4, intRaster.getDataOffset(0));
       
   218 
   191                 dataArray = intRaster.getDataStorage();
   219                 dataArray = intRaster.getDataStorage();
       
   220                 dataArrayLength = 4 * intRaster.getDataStorage().length;
   192                 dataType = DT_INT;
   221                 dataType = DT_INT;
   193                 break;
   222                 break;
   194 
   223 
   195             case BufferedImage.TYPE_3BYTE_BGR:
   224             case BufferedImage.TYPE_3BYTE_BGR:
   196             case BufferedImage.TYPE_4BYTE_ABGR:
   225             case BufferedImage.TYPE_4BYTE_ABGR:
   197                 byteRaster = (ByteComponentRaster)image.getRaster();
   226                 byteRaster = (ByteComponentRaster)image.getRaster();
   198                 nextRowOffset = byteRaster.getScanlineStride();
   227                 nextRowOffset = byteRaster.getScanlineStride();
   199                 int firstBand = image.getSampleModel().getNumBands() - 1;
   228                 int firstBand = image.getSampleModel().getNumBands() - 1;
   200                 offset = byteRaster.getDataOffset(firstBand);
   229                 offset = byteRaster.getDataOffset(firstBand);
   201                 dataArray = byteRaster.getDataStorage();
   230                 dataArray = byteRaster.getDataStorage();
       
   231                 dataArrayLength = byteRaster.getDataStorage().length;
   202                 dataType = DT_BYTE;
   232                 dataType = DT_BYTE;
   203                 break;
   233                 break;
   204 
   234 
   205             case BufferedImage.TYPE_BYTE_GRAY:
   235             case BufferedImage.TYPE_BYTE_GRAY:
   206                 byteRaster = (ByteComponentRaster)image.getRaster();
   236                 byteRaster = (ByteComponentRaster)image.getRaster();
   207                 nextRowOffset = byteRaster.getScanlineStride();
   237                 nextRowOffset = byteRaster.getScanlineStride();
   208                 offset = byteRaster.getDataOffset(0);
   238                 offset = byteRaster.getDataOffset(0);
   209                 dataArray = byteRaster.getDataStorage();
   239                 dataArray = byteRaster.getDataStorage();
       
   240                 dataArrayLength = byteRaster.getDataStorage().length;
   210                 dataType = DT_BYTE;
   241                 dataType = DT_BYTE;
   211                 break;
   242                 break;
   212 
   243 
   213             case BufferedImage.TYPE_USHORT_GRAY:
   244             case BufferedImage.TYPE_USHORT_GRAY:
   214                 shortRaster = (ShortComponentRaster)image.getRaster();
   245                 shortRaster = (ShortComponentRaster)image.getRaster();
   215                 nextRowOffset = shortRaster.getScanlineStride()*2;
   246                 nextRowOffset = safeMult(2, shortRaster.getScanlineStride());
   216                 offset = shortRaster.getDataOffset(0) * 2;
   247                 offset = safeMult(2, shortRaster.getDataOffset(0));
   217                 dataArray = shortRaster.getDataStorage();
   248                 dataArray = shortRaster.getDataStorage();
       
   249                 dataArrayLength = 2 * shortRaster.getDataStorage().length;
   218                 dataType = DT_SHORT;
   250                 dataType = DT_SHORT;
   219                 break;
   251                 break;
   220         }
   252         }
       
   253         verify();
   221     }
   254     }
   222 
   255 
   223     public static boolean isSupported(BufferedImage image) {
   256     public static boolean isSupported(BufferedImage image) {
   224         switch (image.getType()) {
   257         switch (image.getType()) {
   225             case BufferedImage.TYPE_INT_RGB:
   258             case BufferedImage.TYPE_INT_RGB:
   231             case BufferedImage.TYPE_USHORT_GRAY:
   264             case BufferedImage.TYPE_USHORT_GRAY:
   232                 return true;
   265                 return true;
   233         }
   266         }
   234         return false;
   267         return false;
   235     }
   268     }
       
   269 
       
   270     private void verify() throws ImageLayoutException {
       
   271 
       
   272         if (offset < 0 || offset >= dataArrayLength) {
       
   273             throw new ImageLayoutException("Invalid image layout");
       
   274         }
       
   275 
       
   276         int lastPixelOffset = safeMult(nextRowOffset, (height - 1));
       
   277 
       
   278         lastPixelOffset = safeAdd(lastPixelOffset, (width - 1));
       
   279 
       
   280         int off = safeAdd(offset, lastPixelOffset);
       
   281 
       
   282         if (off < 0 || off >= dataArrayLength) {
       
   283             throw new ImageLayoutException("Invalid image layout");
       
   284         }
       
   285     }
       
   286 
       
   287     static int safeAdd(int a, int b) throws ImageLayoutException {
       
   288         long res = a;
       
   289         res += b;
       
   290         if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
       
   291             throw new ImageLayoutException("Invalid image layout");
       
   292         }
       
   293         return (int)res;
       
   294     }
       
   295 
       
   296     static int safeMult(int a, int b) throws ImageLayoutException {
       
   297         long res = a;
       
   298         res *= b;
       
   299         if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
       
   300             throw new ImageLayoutException("Invalid image layout");
       
   301         }
       
   302         return (int)res;
       
   303     }
       
   304 
       
   305     public static class ImageLayoutException extends Exception {
       
   306         public ImageLayoutException(String message) {
       
   307             super(message);
       
   308         }
       
   309     }
   236 }
   310 }