Beispiel #1
0
 private void fill() throws IOException {
   if (!seenEOF) {
     if (pos > 0 && pos < limit) {
       System.arraycopy(inbuf, pos, inbuf, 0, limit - pos);
       limit = limit - pos;
       pos = 0;
     } else if (pos >= limit) {
       pos = 0;
       limit = 0;
     }
     int bsize = inbuf.length;
     while (limit < bsize) {
       int n = underlyingInputStream.read(inbuf, limit, bsize - limit);
       if (n <= 0) {
         seenEOF = true;
         break;
       }
       limit += n;
     }
   }
 }
Beispiel #2
0
  /* this is changed
  public void run() {
  */
  public void produceImage() throws IOException, ImageFormatException {
    /* this is not needed
    ImageConsumer t = target;
    if(t!=null) try {
    */
    try {
      for (int i = 0; i < signature.length; i++)
        if ((signature[i] & 0xFF) != underlyingInputStream.read())
          throw new PNGException("Chunk signature mismatch");

      InputStream is =
          new BufferedInputStream(new InflaterInputStream(inputStream, new Inflater()));

      getData();

      byte[] bPixels = null;
      int[] wPixels = null;
      int pixSize = width;
      int rowStride;
      int logDepth = 0;
      switch (bitDepth) {
        case 1:
          logDepth = 0;
          break;
        case 2:
          logDepth = 1;
          break;
        case 4:
          logDepth = 2;
          break;
        case 8:
          logDepth = 3;
          break;
        case 16:
          logDepth = 4;
          break;
        default:
          throw new PNGException("invalid depth");
      }
      if (interlaceMethod != 0) {
        pixSize *= height;
        rowStride = width;
      } else rowStride = 0;
      int combinedType = colorType | (bitDepth << 3);
      int bitMask = (1 << (bitDepth >= 8 ? 8 : bitDepth)) - 1;
      // Figure out the color model
      switch (colorType) {
        case COLOR | PALETTE:
        case COLOR | PALETTE | ALPHA:
          if (red_map == null) throw new PNGException("palette expected");
          if (alpha_map == null)
            cm = new IndexColorModel(bitDepth, red_map.length, red_map, green_map, blue_map);
          else
            cm =
                new IndexColorModel(
                    bitDepth, red_map.length, red_map, green_map, blue_map, alpha_map);
          bPixels = new byte[pixSize];
          break;
        case GRAY:
          {
            int llog = logDepth >= 4 ? 3 : logDepth;
            if ((cm = greyModels[llog]) == null) {
              int size = 1 << (1 << llog);

              byte ramp[] = new byte[size];
              for (int i = 0; i < size; i++) ramp[i] = (byte) (255 * i / (size - 1));

              if (transparentPixel == -1) {
                cm = new IndexColorModel(bitDepth, ramp.length, ramp, ramp, ramp);
              } else {
                cm =
                    new IndexColorModel(
                        bitDepth, ramp.length, ramp, ramp, ramp, (transparentPixel & 0xFF));
              }
              greyModels[llog] = cm;
            }
          }
          bPixels = new byte[pixSize];
          break;
        case COLOR:
        case COLOR | ALPHA:
        case GRAY | ALPHA:
          cm = ColorModel.getRGBdefault();
          wPixels = new int[pixSize];
          break;
        default:
          throw new PNGException("invalid color type");
      }
      /* this is going to be set in the pixel store
        t.setColorModel(cm);
      t.setHints(interlaceMethod !=0
                 ? ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
                 : ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
                   ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME);
                   */
      // code added to make it work with ImageDecoder architecture
      setDimensions(width, height);
      setColorModel(cm);
      int flags =
          (interlaceMethod != 0
              ? ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
              : ImageConsumer.TOPDOWNLEFTRIGHT
                  | ImageConsumer.COMPLETESCANLINES
                  | ImageConsumer.SINGLEPASS
                  | ImageConsumer.SINGLEFRAME);
      setHints(flags);
      headerComplete();
      // end of adding

      int samplesPerPixel =
          ((colorType & PALETTE) != 0
              ? 1
              : ((colorType & COLOR) != 0 ? 3 : 1) + ((colorType & ALPHA) != 0 ? 1 : 0));
      int bitsPerPixel = samplesPerPixel * bitDepth;
      int bytesPerPixel = (bitsPerPixel + 7) >> 3;
      int pass, passLimit;
      if (interlaceMethod == 0) {
        pass = -1;
        passLimit = 0;
      } else {
        pass = 0;
        passLimit = 7;
      }
      // These loops are far from being tuned.  They're this way to make them easy to
      // debug.  Tuning comes later.
      /* code changed. target not needed here
      while(++pass<=passLimit && (t=target)!=null) {
      */
      while (++pass <= passLimit) {
        int row = startingRow[pass];
        int rowInc = rowIncrement[pass];
        int colInc = colIncrement[pass];
        int bWidth = blockWidth[pass];
        int bHeight = blockHeight[pass];
        int sCol = startingCol[pass];
        int rowPixelWidth = (width - sCol + (colInc - 1)) / colInc;
        int rowByteWidth = ((rowPixelWidth * bitsPerPixel) + 7) >> 3;
        if (rowByteWidth == 0) continue;
        int pixelBufferInc = interlaceMethod == 0 ? rowInc * width : 0;
        int rowOffset = rowStride * row;
        boolean firstRow = true;

        byte[] rowByteBuffer = new byte[rowByteWidth];
        byte[] prevRowByteBuffer = new byte[rowByteWidth];
        /* code changed. target not needed here
        while (row < height && (t=target)!=null) {
        */
        while (row < height) {
          int rowFilter = is.read();
          for (int rowFillPos = 0; rowFillPos < rowByteWidth; ) {
            int n = is.read(rowByteBuffer, rowFillPos, rowByteWidth - rowFillPos);
            if (n <= 0) throw new PNGException("missing data");
            rowFillPos += n;
          }
          filterRow(
              rowByteBuffer,
              firstRow ? null : prevRowByteBuffer,
              rowFilter,
              rowByteWidth,
              bytesPerPixel);
          int col = sCol;
          int spos = 0;
          int pixel = 0;
          while (col < width) {
            if (wPixels != null) {
              switch (combinedType) {
                case COLOR | ALPHA | (8 << 3):
                  wPixels[col + rowOffset] =
                      ((rowByteBuffer[spos] & 0xFF) << 16)
                          | ((rowByteBuffer[spos + 1] & 0xFF) << 8)
                          | ((rowByteBuffer[spos + 2] & 0xFF))
                          | ((rowByteBuffer[spos + 3] & 0xFF) << 24);
                  spos += 4;
                  break;
                case COLOR | ALPHA | (16 << 3):
                  wPixels[col + rowOffset] =
                      ((rowByteBuffer[spos] & 0xFF) << 16)
                          | ((rowByteBuffer[spos + 2] & 0xFF) << 8)
                          | ((rowByteBuffer[spos + 4] & 0xFF))
                          | ((rowByteBuffer[spos + 6] & 0xFF) << 24);
                  spos += 8;
                  break;
                case COLOR | (8 << 3):
                  pixel =
                      ((rowByteBuffer[spos] & 0xFF) << 16)
                          | ((rowByteBuffer[spos + 1] & 0xFF) << 8)
                          | ((rowByteBuffer[spos + 2] & 0xFF));
                  if (pixel != transparentPixel) {
                    pixel |= 0xff000000;
                  }
                  wPixels[col + rowOffset] = pixel;
                  spos += 3;
                  break;
                case COLOR | (16 << 3):
                  pixel =
                      ((rowByteBuffer[spos] & 0xFF) << 16)
                          | ((rowByteBuffer[spos + 2] & 0xFF) << 8)
                          | ((rowByteBuffer[spos + 4] & 0xFF));

                  boolean isTransparent = (transparentPixel_16 != null);
                  for (int i = 0; isTransparent && (i < 6); i++) {
                    isTransparent &=
                        (rowByteBuffer[spos + i] & 0xFF) == (transparentPixel_16[i] & 0xFF);
                  }
                  if (!isTransparent) {
                    pixel |= 0xff000000;
                  }
                  wPixels[col + rowOffset] = pixel;
                  spos += 6;
                  break;
                case GRAY | ALPHA | (8 << 3):
                  {
                    int tx = rowByteBuffer[spos] & 0xFF;
                    wPixels[col + rowOffset] =
                        (tx << 16) | (tx << 8) | tx | ((rowByteBuffer[spos + 1] & 0xFF) << 24);
                  }
                  spos += 2;
                  break;
                case GRAY | ALPHA | (16 << 3):
                  {
                    int tx = rowByteBuffer[spos] & 0xFF;
                    wPixels[col + rowOffset] =
                        (tx << 16) | (tx << 8) | tx | ((rowByteBuffer[spos + 2] & 0xFF) << 24);
                  }
                  spos += 4;
                  break;
                default:
                  throw new PNGException("illegal type/depth");
              }
            } else
              switch (bitDepth) {
                case 1:
                  bPixels[col + rowOffset] =
                      (byte) ((rowByteBuffer[spos >> 3] >> (7 - (spos & 7))) & 1);
                  spos++;
                  break;
                case 2:
                  bPixels[col + rowOffset] =
                      (byte) ((rowByteBuffer[spos >> 2] >> ((3 - (spos & 3)) * 2)) & 3);
                  spos++;
                  break;
                case 4:
                  bPixels[col + rowOffset] =
                      (byte) ((rowByteBuffer[spos >> 1] >> ((1 - (spos & 1)) * 4)) & 15);
                  spos++;
                  break;
                case 8:
                  bPixels[col + rowOffset] = rowByteBuffer[spos++];
                  break;
                case 16:
                  bPixels[col + rowOffset] = rowByteBuffer[spos];
                  spos += 2;
                  break;
                default:
                  throw new PNGException("illegal type/depth");
              }
            /*visit (row, col,
            min (bHeight, height - row),
            min (bWidth, width - col)); */
            col += colInc;
          }
          if (interlaceMethod == 0)
            if (wPixels != null) {
              /* code changed. target not needed here
              t.setPixels(0,row,width,1,cm,wPixels,0,width);
              */
              // code added to make it work with ImageDecoder arch
              sendPixels(0, row, width, 1, wPixels, 0, width);
              // end of adding
            } else {
              /* code changed. target not needed here
              t.setPixels(0,row,width,1,cm,bPixels,0,width);
              */
              // code added to make it work with ImageDecoder arch
              sendPixels(0, row, width, 1, bPixels, 0, width);
              // end of adding
            }
          row += rowInc;
          rowOffset += rowInc * rowStride;
          byte[] T = rowByteBuffer;
          rowByteBuffer = prevRowByteBuffer;
          prevRowByteBuffer = T;
          firstRow = false;
        }
        if (interlaceMethod != 0)
          if (wPixels != null) {
            /* code changed. target not needed here
            t.setPixels(0,0,width,height,cm,wPixels,0,width);
            */
            // code added to make it work with ImageDecoder arch
            sendPixels(0, 0, width, height, wPixels, 0, width);
            // end of adding
          } else {
            /* code changed. target not needed here
            t.setPixels(0,0,width,height,cm,bPixels,0,width);
            */
            // code added to make it work with ImageDecoder arch
            sendPixels(0, 0, width, height, bPixels, 0, width);
            // end of adding
          }
      }

      /* Here, the function "visit(row,column,height,width)" obtains the
      next transmitted pixel and paints a rectangle of the specified
      height and width, whose upper-left corner is at the specified row
      and column, using the color indicated by the pixel.  Note that row
      and column are measured from 0,0 at the upper left corner. */

      /* code not needed, don't deal with target
      if((t=target)!=null) {
        if(properties!=null) t.setProperties(properties);
          t.imageComplete(ImageConsumer.STATICIMAGEDONE);
          */

      imageComplete(ImageConsumer.STATICIMAGEDONE, true);

      /* code not needed }
      is.close();
      */
    } catch (IOException e) {
      if (!aborted) {
        /* code not needed
           if((t=target)!=null) {
           PNGEncoder.prChunk(e.toString(),inbuf,pos,limit-pos,true);
        */
        property("error", e);
        /* code not needed
           t.setProperties(properties);
           t.imageComplete(ImageConsumer.IMAGEERROR|ImageConsumer.STATICIMAGEDONE);
        */
        imageComplete(ImageConsumer.IMAGEERROR | ImageConsumer.STATICIMAGEDONE, true);
        throw e;
      }
    } finally {
      try {
        close();
      } catch (Throwable e) {
      }
      /* code not needed
      target = null;
      endTurn();
      */
    }
  }