Ejemplo n.º 1
0
static ULONG WINAPI PngDecoder_AddRef(IWICBitmapDecoder *iface)
{
    PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}
Ejemplo n.º 2
0
static HRESULT WINAPI JpegDecoder_GetFrame(IWICBitmapDecoder *iface,
    UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
    JpegDecoder *This = impl_from_IWICBitmapDecoder(iface);
    TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);

    if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;

    if (index != 0) return E_INVALIDARG;

    IWICBitmapDecoder_AddRef(iface);
    *ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface;

    return S_OK;
}
Ejemplo n.º 3
0
static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
{
    PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        if (This->png_ptr)
            ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info);
        This->lock.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->lock);
        HeapFree(GetProcessHeap(), 0, This->image_bits);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}
Ejemplo n.º 4
0
static ULONG WINAPI JpegDecoder_Release(IWICBitmapDecoder *iface)
{
    JpegDecoder *This = impl_from_IWICBitmapDecoder(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        This->lock.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->lock);
        if (This->cinfo_initialized) pjpeg_destroy_decompress(&This->cinfo);
        if (This->stream) IStream_Release(This->stream);
        HeapFree(GetProcessHeap(), 0, This->image_data);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}
Ejemplo n.º 5
0
static HRESULT WINAPI PngDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
    void **ppv)
{
    PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid))
    {
        *ppv = &This->IWICBitmapDecoder_iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}
Ejemplo n.º 6
0
static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
    WICDecodeOptions cacheOptions)
{
    PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
    LARGE_INTEGER seek;
    HRESULT hr=S_OK;
    png_bytep *row_pointers=NULL;
    UINT image_size;
    UINT i;
    int color_type, bit_depth;
    png_bytep trans;
    int num_trans;
    png_uint_32 transparency;
    png_color_16p trans_values;
    jmp_buf jmpbuf;

    TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);

    EnterCriticalSection(&This->lock);

    /* initialize libpng */
    This->png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!This->png_ptr)
    {
        hr = E_FAIL;
        goto end;
    }

    This->info_ptr = ppng_create_info_struct(This->png_ptr);
    if (!This->info_ptr)
    {
        ppng_destroy_read_struct(&This->png_ptr, NULL, NULL);
        This->png_ptr = NULL;
        hr = E_FAIL;
        goto end;
    }

    This->end_info = ppng_create_info_struct(This->png_ptr);
    if (!This->info_ptr)
    {
        ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, NULL);
        This->png_ptr = NULL;
        hr = E_FAIL;
        goto end;
    }

    /* set up setjmp/longjmp error handling */
    if (setjmp(jmpbuf))
    {
        ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info);
        HeapFree(GetProcessHeap(), 0, row_pointers);
        This->png_ptr = NULL;
        hr = E_FAIL;
        goto end;
    }
    ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
    ppng_set_crc_action(This->png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);

    /* seek to the start of the stream */
    seek.QuadPart = 0;
    hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
    if (FAILED(hr)) goto end;

    /* set up custom i/o handling */
    ppng_set_read_fn(This->png_ptr, pIStream, user_read_data);

    /* read the header */
    ppng_read_info(This->png_ptr, This->info_ptr);

    /* choose a pixel format */
    color_type = ppng_get_color_type(This->png_ptr, This->info_ptr);
    bit_depth = ppng_get_bit_depth(This->png_ptr, This->info_ptr);

    /* check for color-keyed alpha */
    transparency = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans, &num_trans, &trans_values);

    if (transparency && color_type != PNG_COLOR_TYPE_PALETTE)
    {
        /* expand to RGBA */
        if (color_type == PNG_COLOR_TYPE_GRAY)
        {
            if (bit_depth < 8)
            {
#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
                ppng_set_expand_gray_1_2_4_to_8(This->png_ptr);
#else
                ppng_set_gray_1_2_4_to_8(This->png_ptr);
#endif
                bit_depth = 8;
            }
            ppng_set_gray_to_rgb(This->png_ptr);
        }
        ppng_set_tRNS_to_alpha(This->png_ptr);
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
    }

    switch (color_type)
    {
    case PNG_COLOR_TYPE_GRAY:
        This->bpp = bit_depth;
        switch (bit_depth)
        {
        case 1: This->format = &GUID_WICPixelFormatBlackWhite; break;
        case 2: This->format = &GUID_WICPixelFormat2bppGray; break;
        case 4: This->format = &GUID_WICPixelFormat4bppGray; break;
        case 8: This->format = &GUID_WICPixelFormat8bppGray; break;
        case 16: This->format = &GUID_WICPixelFormat16bppGray; break;
        default:
            ERR("invalid grayscale bit depth: %i\n", bit_depth);
            hr = E_FAIL;
            goto end;
        }
        break;
    case PNG_COLOR_TYPE_GRAY_ALPHA:
        /* WIC does not support grayscale alpha formats so use RGBA */
        ppng_set_gray_to_rgb(This->png_ptr);
        /* fall through */
    case PNG_COLOR_TYPE_RGB_ALPHA:
        This->bpp = bit_depth * 4;
        switch (bit_depth)
        {
        case 8:
            ppng_set_bgr(This->png_ptr);
            This->format = &GUID_WICPixelFormat32bppBGRA;
            break;
        case 16: This->format = &GUID_WICPixelFormat64bppRGBA; break;
        default:
            ERR("invalid RGBA bit depth: %i\n", bit_depth);
            hr = E_FAIL;
            goto end;
        }
        break;
    case PNG_COLOR_TYPE_PALETTE:
        This->bpp = bit_depth;
        switch (bit_depth)
        {
        case 1: This->format = &GUID_WICPixelFormat1bppIndexed; break;
        case 2: This->format = &GUID_WICPixelFormat2bppIndexed; break;
        case 4: This->format = &GUID_WICPixelFormat4bppIndexed; break;
        case 8: This->format = &GUID_WICPixelFormat8bppIndexed; break;
        default:
            ERR("invalid indexed color bit depth: %i\n", bit_depth);
            hr = E_FAIL;
            goto end;
        }
        break;
    case PNG_COLOR_TYPE_RGB:
        This->bpp = bit_depth * 3;
        switch (bit_depth)
        {
        case 8:
            ppng_set_bgr(This->png_ptr);
            This->format = &GUID_WICPixelFormat24bppBGR;
            break;
        case 16: This->format = &GUID_WICPixelFormat48bppRGB; break;
        default:
            ERR("invalid RGB color bit depth: %i\n", bit_depth);
            hr = E_FAIL;
            goto end;
        }
        break;
    default:
        ERR("invalid color type %i\n", color_type);
        hr = E_FAIL;
        goto end;
    }

    /* read the image data */
    This->width = ppng_get_image_width(This->png_ptr, This->info_ptr);
    This->height = ppng_get_image_height(This->png_ptr, This->info_ptr);
    This->stride = This->width * This->bpp;
    image_size = This->stride * This->height;

    This->image_bits = HeapAlloc(GetProcessHeap(), 0, image_size);
    if (!This->image_bits)
    {
        hr = E_OUTOFMEMORY;
        goto end;
    }

    row_pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(png_bytep)*This->height);
    if (!row_pointers)
    {
        hr = E_OUTOFMEMORY;
        goto end;
    }

    for (i=0; i<This->height; i++)
        row_pointers[i] = This->image_bits + i * This->stride;

    ppng_read_image(This->png_ptr, row_pointers);

    HeapFree(GetProcessHeap(), 0, row_pointers);
    row_pointers = NULL;

    ppng_read_end(This->png_ptr, This->end_info);

    This->initialized = TRUE;

end:

    LeaveCriticalSection(&This->lock);

    return hr;
}
Ejemplo n.º 7
0
static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
    WICDecodeOptions cacheOptions)
{
    JpegDecoder *This = impl_from_IWICBitmapDecoder(iface);
    int ret;
    LARGE_INTEGER seek;
    jmp_buf jmpbuf;
    TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions);

    EnterCriticalSection(&This->lock);

    if (This->cinfo_initialized)
    {
        LeaveCriticalSection(&This->lock);
        return WINCODEC_ERR_WRONGSTATE;
    }

    pjpeg_std_error(&This->jerr);

    This->jerr.error_exit = error_exit_fn;
    This->jerr.emit_message = emit_message_fn;

    This->cinfo.err = &This->jerr;

    This->cinfo.client_data = &jmpbuf;

    if (setjmp(jmpbuf))
    {
        LeaveCriticalSection(&This->lock);
        return E_FAIL;
    }

    pjpeg_CreateDecompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_decompress_struct));

    This->cinfo_initialized = TRUE;

    This->stream = pIStream;
    IStream_AddRef(pIStream);

    seek.QuadPart = 0;
    IStream_Seek(This->stream, seek, STREAM_SEEK_SET, NULL);

    This->source_mgr.bytes_in_buffer = 0;
    This->source_mgr.init_source = source_mgr_init_source;
    This->source_mgr.fill_input_buffer = source_mgr_fill_input_buffer;
    This->source_mgr.skip_input_data = source_mgr_skip_input_data;
    This->source_mgr.resync_to_restart = pjpeg_resync_to_restart;
    This->source_mgr.term_source = source_mgr_term_source;

    This->cinfo.src = &This->source_mgr;

    ret = pjpeg_read_header(&This->cinfo, TRUE);

    if (ret != JPEG_HEADER_OK) {
        WARN("Jpeg image in stream has bad format, read header returned %d.\n",ret);
        LeaveCriticalSection(&This->lock);
        return E_FAIL;
    }

    switch (This->cinfo.jpeg_color_space)
    {
    case JCS_GRAYSCALE:
        This->cinfo.out_color_space = JCS_GRAYSCALE;
        break;
    case JCS_RGB:
    case JCS_YCbCr:
        This->cinfo.out_color_space = JCS_RGB;
        break;
    case JCS_CMYK:
    case JCS_YCCK:
        This->cinfo.out_color_space = JCS_CMYK;
        break;
    default:
        ERR("Unknown JPEG color space %i\n", This->cinfo.jpeg_color_space);
        LeaveCriticalSection(&This->lock);
        return E_FAIL;
    }

    if (!pjpeg_start_decompress(&This->cinfo))
    {
        ERR("jpeg_start_decompress failed\n");
        LeaveCriticalSection(&This->lock);
        return E_FAIL;
    }

    This->initialized = TRUE;

    LeaveCriticalSection(&This->lock);

    return S_OK;
}