Beispiel #1
0
static HRESULT WINAPI BitmapClipper_CopyPixels(IWICBitmapClipper *iface,
    const WICRect *rc, UINT stride, UINT buffer_size, BYTE *buffer)
{
    BitmapClipper *This = impl_from_IWICBitmapClipper(iface);
    WICRect rect;

    TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(rc), stride, buffer_size, buffer);

    if (!This->source)
        return WINCODEC_ERR_WRONGSTATE;

    if (rc)
    {
        rect = *rc;

        /* transform to source coordinates */
        rect.X += This->rect.X;
        rect.Y += This->rect.Y;

        if ((rect.X + rect.Width > This->rect.X + This->rect.Width) ||
            (rect.Y + rect.Height > This->rect.Y + This->rect.Height))
            return E_INVALIDARG;

        rc = ▭
    }
    else
        rc = &This->rect;

    return IWICBitmapSource_CopyPixels(This->source, rc, stride, buffer_size, buffer);
}
Beispiel #2
0
static HRESULT WINAPI ColorTransform_CopyPixels(IWICColorTransform *iface,
    const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
    ColorTransform *This = impl_from_IWICColorTransform(iface);
    TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);

    return IWICBitmapSource_CopyPixels(This->dst, prc, cbStride, cbBufferSize, pbBuffer);
}
Beispiel #3
0
static HRESULT WINAPI FlipRotator_CopyPixels(IWICBitmapFlipRotator *iface,
    const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
    FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
    HRESULT hr;
    UINT y;
    UINT srcy, srcwidth, srcheight;
    WICRect rc;
    WICRect rect;

    TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);

    if (!This->source) return WINCODEC_ERR_WRONGSTATE;

    if (This->swap_xy || This->flip_x)
    {
        /* This requires knowledge of the pixel format. */
        FIXME("flipping x and rotating are not implemented\n");
        return E_NOTIMPL;
    }

    hr = IWICBitmapSource_GetSize(This->source, &srcwidth, &srcheight);
    if (FAILED(hr)) return hr;

    if (!prc)
    {
        UINT width, height;
        hr = IWICBitmapSource_GetSize(iface, &width, &height);
        if (FAILED(hr)) return hr;
        rect.X = 0;
        rect.Y = 0;
        rect.Width = width;
        rect.Height = height;
        prc = ▭
    }

    for (y=prc->Y; y - prc->Y < prc->Height; y++)
    {
        if (This->flip_y)
            srcy = srcheight - 1 - y;
        else
            srcy = y;

        rc.X = prc->X;
        rc.Y = srcy;
        rc.Width = prc->Width;
        rc.Height = 1;

        hr = IWICBitmapSource_CopyPixels(This->source, &rc, cbStride, cbStride,
            pbBuffer);

        if (FAILED(hr)) break;

        pbBuffer += cbStride;
    }

    return hr;
}
Beispiel #4
0
static HRESULT WINAPI PngFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
    IWICBitmapSource *pIBitmapSource, WICRect *prc)
{
    PngEncoder *This = encoder_from_frame(iface);
    HRESULT hr;
    WICRect rc;
    WICPixelFormatGUID guid;
    UINT stride;
    BYTE *pixeldata;
    TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc);

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

    if (!This->format)
    {
        hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
        if (FAILED(hr)) return hr;
        hr = IWICBitmapFrameEncode_SetPixelFormat(iface, &guid);
        if (FAILED(hr)) return hr;
    }

    hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
    if (FAILED(hr)) return hr;
    if (memcmp(&guid, This->format->guid, sizeof(GUID)) != 0)
    {
        /* FIXME: should use WICConvertBitmapSource to convert */
        ERR("format %s unsupported\n", debugstr_guid(&guid));
        return E_FAIL;
    }

    if (This->xres == 0.0 || This->yres == 0.0)
    {
        double xres, yres;
        hr = IWICBitmapSource_GetResolution(pIBitmapSource, &xres, &yres);
        if (FAILED(hr)) return hr;
        hr = IWICBitmapFrameEncode_SetResolution(iface, xres, yres);
        if (FAILED(hr)) return hr;
    }

    if (!prc)
    {
        UINT width, height;
        hr = IWICBitmapSource_GetSize(pIBitmapSource, &width, &height);
        if (FAILED(hr)) return hr;
        rc.X = 0;
        rc.Y = 0;
        rc.Width = width;
        rc.Height = height;
        prc = &rc;
    }

    if (prc->Width != This->width) return E_INVALIDARG;

    stride = (This->format->bpp * This->width + 7)/8;

    pixeldata = HeapAlloc(GetProcessHeap(), 0, stride * prc->Height);
    if (!pixeldata) return E_OUTOFMEMORY;

    hr = IWICBitmapSource_CopyPixels(pIBitmapSource, prc, stride,
        stride*prc->Height, pixeldata);

    if (SUCCEEDED(hr))
    {
        hr = IWICBitmapFrameEncode_WritePixels(iface, prc->Height, stride,
            stride*prc->Height, pixeldata);
    }

    HeapFree(GetProcessHeap(), 0, pixeldata);

    return hr;
}
Beispiel #5
0
static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface,
    IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option,
    IWICBitmap **ppIBitmap)
{
    IWICBitmap *result;
    IWICBitmapLock *lock;
    IWICPalette *palette;
    UINT width, height;
    WICPixelFormatGUID pixelformat = {0};
    HRESULT hr;
    WICRect rc;
    double dpix, dpiy;
    IWICComponentInfo *info;
    IWICPixelFormatInfo2 *formatinfo;
    WICPixelFormatNumericRepresentation format_type;

    TRACE("(%p,%p,%u,%p)\n", iface, piBitmapSource, option, ppIBitmap);

    if (!piBitmapSource || !ppIBitmap)
        return E_INVALIDARG;

    hr = IWICBitmapSource_GetSize(piBitmapSource, &width, &height);

    if (SUCCEEDED(hr))
        hr = IWICBitmapSource_GetPixelFormat(piBitmapSource, &pixelformat);

    if (SUCCEEDED(hr))
        hr = CreateComponentInfo(&pixelformat, &info);

    if (SUCCEEDED(hr))
    {
        hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void**)&formatinfo);

        if (SUCCEEDED(hr))
        {
            hr = IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo, &format_type);

            IWICPixelFormatInfo2_Release(formatinfo);
        }

        IWICComponentInfo_Release(info);
    }

    if (SUCCEEDED(hr))
        hr = BitmapImpl_Create(width, height, &pixelformat, option, &result);

    if (SUCCEEDED(hr))
    {
        hr = IWICBitmap_Lock(result, NULL, WICBitmapLockWrite, &lock);
        if (SUCCEEDED(hr))
        {
            UINT stride, buffersize;
            BYTE *buffer;
            rc.X = rc.Y = 0;
            rc.Width = width;
            rc.Height = height;

            hr = IWICBitmapLock_GetStride(lock, &stride);

            if (SUCCEEDED(hr))
                hr = IWICBitmapLock_GetDataPointer(lock, &buffersize, &buffer);

            if (SUCCEEDED(hr))
                hr = IWICBitmapSource_CopyPixels(piBitmapSource, &rc, stride,
                    buffersize, buffer);

            IWICBitmapLock_Release(lock);
        }

        if (SUCCEEDED(hr))
            hr = PaletteImpl_Create(&palette);

        if (SUCCEEDED(hr) && (format_type == WICPixelFormatNumericRepresentationUnspecified ||
                              format_type == WICPixelFormatNumericRepresentationIndexed))
        {
            hr = IWICBitmapSource_CopyPalette(piBitmapSource, palette);

            if (SUCCEEDED(hr))
                hr = IWICBitmap_SetPalette(result, palette);
            else
                hr = S_OK;

            IWICPalette_Release(palette);
        }

        if (SUCCEEDED(hr))
        {
            hr = IWICBitmapSource_GetResolution(piBitmapSource, &dpix, &dpiy);

            if (SUCCEEDED(hr))
                hr = IWICBitmap_SetResolution(result, dpix, dpiy);
            else
                hr = S_OK;
        }

        if (SUCCEEDED(hr))
            *ppIBitmap = result;
        else
            IWICBitmap_Release(result);
    }

    return hr;
}
Beispiel #6
0
HRESULT WINAPI IWICBitmapSource_CopyPixels_Proxy_W(IWICBitmapSource *iface,
    const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
    return IWICBitmapSource_CopyPixels(iface, prc, cbStride, cbBufferSize, pbBuffer);
}
Beispiel #7
0
static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
    IWICBitmapSource *pIBitmapSource, WICRect *prc)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    HRESULT hr;
    WICRect rc;
    WICPixelFormatGUID guid;
    TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc);

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

    if (!This->format)
    {
        hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
        if (FAILED(hr)) return hr;
        hr = BmpFrameEncode_SetPixelFormat(iface, &guid);
        if (FAILED(hr)) return hr;
    }

    hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
    if (FAILED(hr)) return hr;
    if (memcmp(&guid, This->format->guid, sizeof(GUID)) != 0)
    {
        /* should use WICConvertBitmapSource to convert, but that's unimplemented */
        ERR("format %s unsupported\n", debugstr_guid(&guid));
        return E_FAIL;
    }

    if (This->xres == 0.0 || This->yres == 0.0)
    {
        double xres, yres;
        hr = IWICBitmapSource_GetResolution(pIBitmapSource, &xres, &yres);
        if (FAILED(hr)) return hr;
        hr = BmpFrameEncode_SetResolution(iface, xres, yres);
        if (FAILED(hr)) return hr;
    }

    if (!prc)
    {
        UINT width, height;
        hr = IWICBitmapSource_GetSize(pIBitmapSource, &width, &height);
        if (FAILED(hr)) return hr;
        rc.X = 0;
        rc.Y = 0;
        rc.Width = width;
        rc.Height = height;
        prc = &rc;
    }

    if (prc->Width != This->width) return E_INVALIDARG;

    hr = BmpFrameEncode_AllocateBits(This);
    if (FAILED(hr)) return hr;

    hr = IWICBitmapSource_CopyPixels(pIBitmapSource, prc, This->stride,
        This->stride*(This->height-This->lineswritten),
        This->bits + This->stride*This->lineswritten);

    This->lineswritten += prc->Height;

    return S_OK;
}
Beispiel #8
0
static void compare_bitmap_data(const struct bitmap_data *expect, IWICBitmapSource *source, const char *name)
{
    BYTE *converted_bits;
    UINT width, height;
    double xres, yres;
    WICRect prc;
    UINT stride, buffersize;
    GUID dst_pixelformat;
    HRESULT hr;

    hr = IWICBitmapSource_GetSize(source, &width, &height);
    ok(SUCCEEDED(hr), "GetSize(%s) failed, hr=%x\n", name, hr);
    ok(width == expect->width, "expecting %u, got %u (%s)\n", expect->width, width, name);
    ok(height == expect->height, "expecting %u, got %u (%s)\n", expect->height, height, name);

    hr = IWICBitmapSource_GetResolution(source, &xres, &yres);
    ok(SUCCEEDED(hr), "GetResolution(%s) failed, hr=%x\n", name, hr);
    ok(fabs(xres - expect->xres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->xres, xres, name);
    ok(fabs(yres - expect->yres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->yres, yres, name);

    hr = IWICBitmapSource_GetPixelFormat(source, &dst_pixelformat);
    ok(SUCCEEDED(hr), "GetPixelFormat(%s) failed, hr=%x\n", name, hr);
    ok(IsEqualGUID(&dst_pixelformat, expect->format), "got unexpected pixel format (%s)\n", name);

    prc.X = 0;
    prc.Y = 0;
    prc.Width = expect->width;
    prc.Height = expect->height;

    stride = (expect->bpp * expect->width + 7) / 8;
    buffersize = stride * expect->height;

    converted_bits = HeapAlloc(GetProcessHeap(), 0, buffersize);
    hr = IWICBitmapSource_CopyPixels(source, &prc, stride, buffersize, converted_bits);
    ok(SUCCEEDED(hr), "CopyPixels(%s) failed, hr=%x\n", name, hr);
    if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppBGR))
    {
        /* ignore the padding byte when comparing data */
        UINT i;
        BOOL equal=TRUE;
        const DWORD *a=(const DWORD*)expect->bits, *b=(const DWORD*)converted_bits;
        for (i=0; i<(buffersize/4); i++)
            if ((a[i]&0xffffff) != (b[i]&0xffffff))
            {
                equal = FALSE;
                break;
            }
        ok(equal, "unexpected pixel data (%s)\n", name);
    }
    else
        ok(memcmp(expect->bits, converted_bits, buffersize) == 0, "unexpected pixel data (%s)\n", name);

    /* Test with NULL rectangle - should copy the whole bitmap */
    hr = IWICBitmapSource_CopyPixels(source, NULL, stride, buffersize, converted_bits);
    ok(SUCCEEDED(hr), "CopyPixels(%s,rc=NULL) failed, hr=%x\n", name, hr);
    if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppBGR))
    {
        /* ignore the padding byte when comparing data */
        UINT i;
        BOOL equal=TRUE;
        const DWORD *a=(const DWORD*)expect->bits, *b=(const DWORD*)converted_bits;
        for (i=0; i<(buffersize/4); i++)
            if ((a[i]&0xffffff) != (b[i]&0xffffff))
            {
                equal = FALSE;
                break;
            }
        ok(equal, "unexpected pixel data with rc=NULL (%s)\n", name);
    }
    else
        ok(memcmp(expect->bits, converted_bits, buffersize) == 0, "unexpected pixel data with rc=NULL (%s)\n", name);

    HeapFree(GetProcessHeap(), 0, converted_bits);
}
Beispiel #9
0
static HRESULT WINAPI BitmapScaler_CopyPixels(IWICBitmapScaler *iface,
    const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
    BitmapScaler *This = impl_from_IWICBitmapScaler(iface);
    HRESULT hr;
    WICRect dest_rect;
    WICRect src_rect_ul, src_rect_br, src_rect;
    BYTE **src_rows;
    BYTE *src_bits;
    ULONG bytesperrow;
    ULONG src_bytesperrow;
    ULONG buffer_size;
    UINT y;

    TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);

    EnterCriticalSection(&This->lock);

    if (!This->source)
    {
        hr = WINCODEC_ERR_WRONGSTATE;
        goto end;
    }

    if (prc)
        dest_rect = *prc;
    else
    {
        dest_rect.X = dest_rect.Y = 0;
        dest_rect.Width = This->width;
        dest_rect.Height = This->height;
    }

    if (dest_rect.X < 0 || dest_rect.Y < 0 ||
        dest_rect.X+dest_rect.Width > This->width|| dest_rect.Y+dest_rect.Height > This->height)
    {
        hr = E_INVALIDARG;
        goto end;
    }

    bytesperrow = ((This->bpp * dest_rect.Width)+7)/8;

    if (cbStride < bytesperrow)
    {
        hr = E_INVALIDARG;
        goto end;
    }

    if ((cbStride * dest_rect.Height) > cbBufferSize)
    {
        hr = E_INVALIDARG;
        goto end;
    }

    /* MSDN recommends calling CopyPixels once for each scanline from top to
     * bottom, and claims codecs optimize for this. Ideally, when called in this
     * way, we should avoid requesting a scanline from the source more than
     * once, by saving the data that will be useful for the next scanline after
     * the call returns. The GetRequiredSourceRect/CopyScanline functions are
     * designed to make it possible to do this in a generic way, but for now we
     * just grab all the data we need in each call. */

    This->fn_get_required_source_rect(This, dest_rect.X, dest_rect.Y, &src_rect_ul);
    This->fn_get_required_source_rect(This, dest_rect.X+dest_rect.Width-1,
        dest_rect.Y+dest_rect.Height-1, &src_rect_br);

    src_rect.X = src_rect_ul.X;
    src_rect.Y = src_rect_ul.Y;
    src_rect.Width = src_rect_br.Width + src_rect_br.X - src_rect_ul.X;
    src_rect.Height = src_rect_br.Height + src_rect_br.Y - src_rect_ul.Y;

    src_bytesperrow = (src_rect.Width * This->bpp + 7)/8;
    buffer_size = src_bytesperrow * src_rect.Height;

    src_rows = HeapAlloc(GetProcessHeap(), 0, sizeof(BYTE*) * src_rect.Height);
    src_bits = HeapAlloc(GetProcessHeap(), 0, buffer_size);

    if (!src_rows || !src_bits)
    {
        HeapFree(GetProcessHeap(), 0, src_rows);
        HeapFree(GetProcessHeap(), 0, src_bits);
        hr = E_OUTOFMEMORY;
        goto end;
    }

    for (y=0; y<src_rect.Height; y++)
        src_rows[y] = src_bits + y * src_bytesperrow;

    hr = IWICBitmapSource_CopyPixels(This->source, &src_rect, src_bytesperrow,
        buffer_size, src_bits);

    if (SUCCEEDED(hr))
    {
        for (y=0; y < dest_rect.Height; y++)
        {
            This->fn_copy_scanline(This, dest_rect.X, dest_rect.Y+y, dest_rect.Width,
                src_rows, src_rect.X, src_rect.Y, pbBuffer + cbStride * y);
        }
    }

    HeapFree(GetProcessHeap(), 0, src_rows);
    HeapFree(GetProcessHeap(), 0, src_bits);

end:
    LeaveCriticalSection(&This->lock);

    return hr;
}