2 * Copyright 2020 Esme Povirk
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 HRESULT CDECL
decoder_initialize(struct decoder
*decoder
, IStream
*stream
, struct decoder_stat
*st
)
21 return decoder
->vtable
->initialize(decoder
, stream
, st
);
24 HRESULT CDECL
decoder_get_frame_info(struct decoder
*decoder
, UINT frame
, struct decoder_frame
*info
)
26 return decoder
->vtable
->get_frame_info(decoder
, frame
, info
);
29 HRESULT CDECL
decoder_copy_pixels(struct decoder
*decoder
, UINT frame
,
30 const WICRect
*prc
, UINT stride
, UINT buffersize
, BYTE
*buffer
)
32 return decoder
->vtable
->copy_pixels(decoder
, frame
, prc
, stride
, buffersize
, buffer
);
35 HRESULT CDECL
decoder_get_metadata_blocks(struct decoder
*decoder
, UINT frame
, UINT
*count
, struct decoder_block
**blocks
)
37 return decoder
->vtable
->get_metadata_blocks(decoder
, frame
, count
, blocks
);
40 HRESULT CDECL
decoder_get_color_context(struct decoder
*decoder
, UINT frame
,
41 UINT num
, BYTE
**data
, DWORD
*datasize
)
43 return decoder
->vtable
->get_color_context(decoder
, frame
, num
, data
, datasize
);
46 void CDECL
decoder_destroy(struct decoder
*decoder
)
48 decoder
->vtable
->destroy(decoder
);
51 HRESULT CDECL
encoder_initialize(struct encoder
*encoder
, IStream
*stream
)
53 return encoder
->vtable
->initialize(encoder
, stream
);
56 HRESULT CDECL
encoder_get_supported_format(struct encoder
* encoder
, GUID
*pixel_format
, DWORD
*bpp
, BOOL
*indexed
)
58 return encoder
->vtable
->get_supported_format(encoder
, pixel_format
, bpp
, indexed
);
61 HRESULT CDECL
encoder_create_frame(struct encoder
* encoder
, const struct encoder_frame
*frame
)
63 return encoder
->vtable
->create_frame(encoder
, frame
);
66 HRESULT CDECL
encoder_write_lines(struct encoder
* encoder
, BYTE
*data
, DWORD line_count
, DWORD stride
)
68 return encoder
->vtable
->write_lines(encoder
, data
, line_count
, stride
);
71 HRESULT CDECL
encoder_commit_frame(struct encoder
* encoder
)
73 return encoder
->vtable
->commit_frame(encoder
);
76 HRESULT CDECL
encoder_commit_file(struct encoder
* encoder
)
78 return encoder
->vtable
->commit_file(encoder
);
81 void CDECL
encoder_destroy(struct encoder
*encoder
)
83 encoder
->vtable
->destroy(encoder
);
86 HRESULT
copy_pixels(UINT bpp
, const BYTE
*srcbuffer
,
87 UINT srcwidth
, UINT srcheight
, INT srcstride
,
88 const WICRect
*rc
, UINT dststride
, UINT dstbuffersize
, BYTE
*dstbuffer
)
91 UINT row_offset
; /* number of bits into the source rows where the data starts */
98 rect
.Width
= srcwidth
;
99 rect
.Height
= srcheight
;
104 if (rc
->X
< 0 || rc
->Y
< 0 || rc
->X
+rc
->Width
> srcwidth
|| rc
->Y
+rc
->Height
> srcheight
)
108 bytesperrow
= ((bpp
* rc
->Width
)+7)/8;
110 if (dststride
< bytesperrow
)
113 if ((dststride
* (rc
->Height
-1)) + bytesperrow
> dstbuffersize
)
116 /* if the whole bitmap is copied and the buffer format matches then it's a matter of a single memcpy */
117 if (rc
->X
== 0 && rc
->Y
== 0 && rc
->Width
== srcwidth
&& rc
->Height
== srcheight
&&
118 srcstride
== dststride
&& srcstride
== bytesperrow
)
120 memcpy(dstbuffer
, srcbuffer
, srcstride
* srcheight
);
124 row_offset
= rc
->X
* bpp
;
126 if (row_offset
% 8 == 0)
128 /* everything lines up on a byte boundary */
133 src
= srcbuffer
+ (row_offset
/ 8) + srcstride
* rc
->Y
;
135 for (row
=0; row
< rc
->Height
; row
++)
137 memcpy(dst
, src
, bytesperrow
);
145 /* we have to do a weird bitwise copy. eww. */
146 FIXME("cannot reliably copy bitmap data if bpp < 8\n");
151 static inline ULONG
read_ulong_be(BYTE
* data
)
153 return data
[0] << 24 | data
[1] << 16 | data
[2] << 8 | data
[3];
156 HRESULT
read_png_chunk(IStream
*stream
, BYTE
*type
, BYTE
**data
, ULONG
*data_size
)
162 hr
= stream_read(stream
, header
, 8, &bytesread
);
163 if (FAILED(hr
) || bytesread
< 8)
170 *data_size
= read_ulong_be(&header
[0]);
172 memcpy(type
, &header
[4], 4);
176 *data
= RtlAllocateHeap(GetProcessHeap(), 0, *data_size
);
178 return E_OUTOFMEMORY
;
180 hr
= stream_read(stream
, *data
, *data_size
, &bytesread
);
182 if (FAILED(hr
) || bytesread
< *data_size
)
186 RtlFreeHeap(GetProcessHeap(), 0, *data
);
191 /* Windows ignores CRC of the chunk */
197 void reverse_bgr8(UINT bytesperpixel
, LPBYTE bits
, UINT width
, UINT height
, INT stride
)
202 for (y
=0; y
<height
; y
++)
204 pixel
= bits
+ stride
* y
;
206 for (x
=0; x
<width
; x
++)
211 pixel
+= bytesperpixel
;