Beispiel #1
0
int
SplashDecodePng(Splash * splash, png_rw_ptr read_func, void *io_ptr)
{
    int stride;
    ImageFormat srcFormat;
    png_uint_32 i, rowbytes;
    png_bytepp row_pointers = NULL;
    png_bytep image_data = NULL;
    int success = 0;
    double gamma;

    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;

    png_uint_32 width, height;
    int bit_depth, color_type;

    ImageRect srcRect, dstRect;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr) {
        goto done;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        goto done;
    }

    if (setjmp(png_ptr->jmpbuf)) {
        goto done;
    }

    png_ptr->io_ptr = io_ptr;
    png_ptr->read_data_fn = read_func;

    png_set_sig_bytes(png_ptr, SIG_BYTES);      /* we already read the 8 signature bytes */

    png_read_info(png_ptr, info_ptr);   /* read all PNG info up to image data */

    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
        NULL, NULL, NULL);

    /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
     * transparency chunks to full alpha channel; strip 16-bit-per-sample
     * images to 8 bits per sample; and convert grayscale to RGB[A]
     * this may be sub-optimal but this simplifies implementation */

    png_set_expand(png_ptr);
    png_set_tRNS_to_alpha(png_ptr);
    png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
    png_set_strip_16(png_ptr);
    png_set_gray_to_rgb(png_ptr);

    if (png_get_gAMA(png_ptr, info_ptr, &gamma))
        png_set_gamma(png_ptr, 2.2, gamma);

    png_read_update_info(png_ptr, info_ptr);

    rowbytes = png_get_rowbytes(png_ptr, info_ptr);

    if (!SAFE_TO_ALLOC(rowbytes, height)) {
        goto done;
    }

    if ((image_data = (unsigned char *) malloc(rowbytes * height)) == NULL) {
        goto done;
    }

    if (!SAFE_TO_ALLOC(height, sizeof(png_bytep))) {
        goto done;
    }
    if ((row_pointers = (png_bytepp) malloc(height * sizeof(png_bytep)))
            == NULL) {
        goto done;
    }

    for (i = 0; i < height; ++i)
        row_pointers[i] = image_data + i * rowbytes;

    png_read_image(png_ptr, row_pointers);

    SplashCleanup(splash);

    splash->width = width;
    splash->height = height;

    if (!SAFE_TO_ALLOC(splash->width, splash->imageFormat.depthBytes)) {
        goto done;
    }
    stride = splash->width * splash->imageFormat.depthBytes;

    if (!SAFE_TO_ALLOC(splash->height, stride)) {
        goto done;
    }
    splash->frameCount = 1;
    splash->frames = (SplashImage *)
        malloc(sizeof(SplashImage) * splash->frameCount);

    if (splash->frames == NULL) {
        goto done;
    }

    splash->loopCount = 1;
    splash->frames[0].bitmapBits = malloc(stride * splash->height);
    if (splash->frames[0].bitmapBits == NULL) {
        free(splash->frames);
        goto done;
    }
    splash->frames[0].delay = 0;

    /* FIXME: sort out the real format */
    initFormat(&srcFormat, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
    srcFormat.byteOrder = BYTE_ORDER_MSBFIRST;

    initRect(&srcRect, 0, 0, width, height, 1, rowbytes,
        image_data, &srcFormat);
    initRect(&dstRect, 0, 0, width, height, 1, stride,
        splash->frames[0].bitmapBits, &splash->imageFormat);
    convertRect(&srcRect, &dstRect, CVT_COPY);

    SplashInitFrameShape(splash, 0);

    png_read_end(png_ptr, NULL);
    success = 1;

  done:
    free(row_pointers);
    free(image_data);
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    return success;
}
Beispiel #2
0
void *tsi_ReAllocArray(register tsiMemObject *t, void *pIn, size_t size, size_t n) {
    tsi_Assert(t, SAFE_TO_ALLOC(size, n), T2K_ERR_MEM_MALLOC_FAILED);

    return tsi_ReAllocMem(t, pIn, size*n);
}
Beispiel #3
0
int
SplashDecodeJpeg(Splash * splash, struct jpeg_decompress_struct *cinfo)
{
    int rowStride, stride;
    JSAMPARRAY buffer;
    ImageFormat srcFormat;

    jpeg_read_header(cinfo, TRUE);
    jpeg_start_decompress(cinfo);

    splash->width = cinfo->output_width;
    splash->height = cinfo->output_height;

    if (!SAFE_TO_ALLOC(splash->imageFormat.depthBytes, splash->width)) {
        return 0;
    }
    stride = splash->width * splash->imageFormat.depthBytes;

    if (!SAFE_TO_ALLOC(stride, splash->height)) {
        return 0;
    }
    if (!SAFE_TO_ALLOC(cinfo->output_width, cinfo->output_components)) {
        return 0;
    }

    splash->frameCount = 1;
    splash->frames = (SplashImage *) malloc(sizeof(SplashImage) *
        splash->frameCount);
    if (splash->frames == NULL) {
        return 0;
    }
    memset(splash->frames, 0, sizeof(SplashImage) *
        splash->frameCount);

    splash->loopCount = 1;
    splash->frames[0].delay = 0;
    splash->frames[0].bitmapBits = malloc(stride * splash->height);
    if (splash->frames[0].bitmapBits == NULL) {
        free(splash->frames);
        return 0;
    }

    rowStride = cinfo->output_width * cinfo->output_components;

    buffer = (*cinfo->mem->alloc_sarray)
        ((j_common_ptr) cinfo, JPOOL_IMAGE, rowStride, 1);
    if (buffer == NULL) {
        free(splash->frames[0].bitmapBits);
        free(splash->frames);
        return 0;
    }

    initFormat(&srcFormat, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000);
    srcFormat.byteOrder = BYTE_ORDER_LSBFIRST;
    srcFormat.depthBytes = 3;
    srcFormat.fixedBits = 0xFF000000;

    splash->maskRequired = 0;   // reset maskRequired as JPEG can't be transparent

    while (cinfo->output_scanline < cinfo->output_height) {
        rgbquad_t *out =
            (rgbquad_t *) ((byte_t *) splash->frames[0].bitmapBits +
                cinfo->output_scanline * stride);

        jpeg_read_scanlines(cinfo, buffer, 1);
        convertLine(buffer[0], sizeof(JSAMPLE) * 3, out,
            splash->imageFormat.depthBytes, cinfo->output_width, &srcFormat,
            &splash->imageFormat, CVT_COPY, NULL, 0, NULL,
            cinfo->output_scanline, 0);
    }
    jpeg_finish_decompress(cinfo);

    return 1;
}