コード例 #1
0
ファイル: pngformat.c プロジェクト: bilboed/wine
static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
    UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
{
    PngEncoder *This = encoder_from_frame(iface);
    png_byte **row_pointers=NULL;
    UINT i;
    jmp_buf jmpbuf;
    TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);

    if (!This->frame_initialized || !This->width || !This->height || !This->format)
        return WINCODEC_ERR_WRONGSTATE;

    if (lineCount == 0 || lineCount + This->lines_written > This->height)
        return E_INVALIDARG;

    /* set up setjmp/longjmp error handling */
    if (setjmp(jmpbuf))
    {
        HeapFree(GetProcessHeap(), 0, row_pointers);
        return E_FAIL;
    }
    ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);

    if (!This->info_written)
    {
        ppng_set_IHDR(This->png_ptr, This->info_ptr, This->width, This->height,
            This->format->bit_depth, This->format->color_type, PNG_INTERLACE_NONE,
            PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

        if (This->xres != 0.0 && This->yres != 0.0)
        {
            ppng_set_pHYs(This->png_ptr, This->info_ptr, (This->xres+0.0127) / 0.0254,
                (This->yres+0.0127) / 0.0254, PNG_RESOLUTION_METER);
        }

        ppng_write_info(This->png_ptr, This->info_ptr);

        if (This->format->remove_filler)
            ppng_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER);

        if (This->format->swap_rgb)
            ppng_set_bgr(This->png_ptr);

        This->info_written = TRUE;
    }

    row_pointers = HeapAlloc(GetProcessHeap(), 0, lineCount * sizeof(png_byte*));
    if (!row_pointers)
        return E_OUTOFMEMORY;

    for (i=0; i<lineCount; i++)
        row_pointers[i] = pbPixels + cbStride * i;

    ppng_write_rows(This->png_ptr, row_pointers, lineCount);
    This->lines_written += lineCount;

    HeapFree(GetProcessHeap(), 0, row_pointers);

    return S_OK;
}
コード例 #2
0
ファイル: pngformat.c プロジェクト: DeltaYang/wine
static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
    UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
{
    PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
    png_byte **row_pointers=NULL;
    UINT i;
    jmp_buf jmpbuf;
    TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);

    EnterCriticalSection(&This->lock);

    if (!This->frame_initialized || !This->width || !This->height || !This->format)
    {
        LeaveCriticalSection(&This->lock);
        return WINCODEC_ERR_WRONGSTATE;
    }

    if (lineCount == 0 || lineCount + This->lines_written > This->height)
    {
        LeaveCriticalSection(&This->lock);
        return E_INVALIDARG;
    }

    /* set up setjmp/longjmp error handling */
    if (setjmp(jmpbuf))
    {
        LeaveCriticalSection(&This->lock);
        HeapFree(GetProcessHeap(), 0, row_pointers);
        return E_FAIL;
    }
    ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);

    if (!This->info_written)
    {
        if (This->interlace)
        {
            /* libpng requires us to write all data multiple times in this case. */
            This->stride = (This->format->bpp * This->width + 7)/8;
            This->data = HeapAlloc(GetProcessHeap(), 0, This->height * This->stride);
            if (!This->data)
            {
                LeaveCriticalSection(&This->lock);
                return E_OUTOFMEMORY;
            }
        }

        ppng_set_IHDR(This->png_ptr, This->info_ptr, This->width, This->height,
            This->format->bit_depth, This->format->color_type,
            This->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE,
            PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

        if (This->xres != 0.0 && This->yres != 0.0)
        {
            ppng_set_pHYs(This->png_ptr, This->info_ptr, (This->xres+0.0127) / 0.0254,
                (This->yres+0.0127) / 0.0254, PNG_RESOLUTION_METER);
        }

        ppng_write_info(This->png_ptr, This->info_ptr);

        if (This->format->remove_filler)
            ppng_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER);

        if (This->format->swap_rgb)
            ppng_set_bgr(This->png_ptr);

        if (This->interlace)
            This->passes = ppng_set_interlace_handling(This->png_ptr);

        This->info_written = TRUE;
    }

    if (This->interlace)
    {
        /* Just store the data so we can write it in multiple passes in Commit. */
        for (i=0; i<lineCount; i++)
            memcpy(This->data + This->stride * (This->lines_written + i),
                   pbPixels + cbStride * i,
                   This->stride);

        This->lines_written += lineCount;

        LeaveCriticalSection(&This->lock);
        return S_OK;
    }

    row_pointers = HeapAlloc(GetProcessHeap(), 0, lineCount * sizeof(png_byte*));
    if (!row_pointers)
    {
        LeaveCriticalSection(&This->lock);
        return E_OUTOFMEMORY;
    }

    for (i=0; i<lineCount; i++)
        row_pointers[i] = pbPixels + cbStride * i;

    ppng_write_rows(This->png_ptr, row_pointers, lineCount);
    This->lines_written += lineCount;

    LeaveCriticalSection(&This->lock);

    HeapFree(GetProcessHeap(), 0, row_pointers);

    return S_OK;
}