50#define CRAM_MAGIC mmioFOURCC('C', 'R', 'A', 'M')
51#define MSVC_MAGIC mmioFOURCC('M', 'S', 'V', 'C')
52#define WHAM_MAGIC mmioFOURCC('W', 'H', 'A', 'M')
53#define compare_fourcc(fcc1, fcc2) (((fcc1)^(fcc2))&~0x20202020)
55#define PALETTE_COUNT 256
56#define LE_16(x) ((((const uint8_t *)(x))[1] << 8) | ((const uint8_t *)(x))[0])
59#define CHECK_STREAM_PTR(n) \
60 if ((stream_ptr + n) > buf_size ) { \
61 WARN("stream_ptr out of bounds (%d >= %d)\n", \
62 stream_ptr + n, buf_size); \
82 int block_ptr, pixel_ptr;
86 int blocks_wide, blocks_high;
92 unsigned char byte_a, byte_b;
95 unsigned char colors[8];
99 blocks_wide =
width / 4;
101 total_blocks = blocks_wide * blocks_high;
109 for (block_y = blocks_high; block_y > 0; block_y--) {
111 block_ptr = ((block_y * 4) - 1) *
stride;
113 block_ptr = ((blocks_high - block_y) * 4) *
stride;
115 for (block_x = blocks_wide; block_x > 0; block_x--) {
118 block_ptr += block_inc;
124 pixel_ptr = block_ptr;
128 byte_a =
buf[stream_ptr++];
129 byte_b =
buf[stream_ptr++];
132 if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0))
134 else if ((byte_b & 0xFC) == 0x84) {
136 skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
137 }
else if (byte_b < 0x80) {
139 flags = (byte_b << 8) | byte_a;
142 colors[0] =
buf[stream_ptr++];
143 colors[1] =
buf[stream_ptr++];
145 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
146 for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
148 pixel_ptr -= row_dec;
150 }
else if (byte_b >= 0x90) {
152 flags = (byte_b << 8) | byte_a;
158 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
159 for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
161 colors[((pixel_y & 0x2) << 1) +
162 (pixel_x & 0x2) + ((
flags & 0x1) ^ 1)];
163 pixel_ptr -= row_dec;
169 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
170 for (pixel_x = 0; pixel_x < 4; pixel_x++)
171 pixels[pixel_ptr++] = colors[0];
172 pixel_ptr -= row_dec;
176 block_ptr += block_inc;
186 int block_ptr, pixel_ptr;
188 int pixel_x, pixel_y;
189 int block_x, block_y;
190 int blocks_wide, blocks_high;
196 unsigned char byte_a, byte_b;
197 unsigned short flags;
199 unsigned short colors[8];
203 blocks_wide =
width / 4;
205 total_blocks = blocks_wide * blocks_high;
213 for (block_y = blocks_high; block_y > 0; block_y--) {
215 block_ptr = ((block_y * 4) - 1) *
stride;
217 block_ptr = ((blocks_high - block_y) * 4) *
stride;
219 for (block_x = blocks_wide; block_x > 0; block_x--) {
222 block_ptr += block_inc;
228 pixel_ptr = block_ptr;
232 byte_a =
buf[stream_ptr++];
233 byte_b =
buf[stream_ptr++];
236 if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0)) {
238 }
else if ((byte_b & 0xFC) == 0x84) {
240 skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
241 }
else if (byte_b < 0x80) {
243 flags = (byte_b << 8) | byte_a;
246 colors[0] =
LE_16(&
buf[stream_ptr]);
248 colors[1] =
LE_16(&
buf[stream_ptr]);
251 if (colors[0] & 0x8000) {
254 colors[2] =
LE_16(&
buf[stream_ptr]);
256 colors[3] =
LE_16(&
buf[stream_ptr]);
258 colors[4] =
LE_16(&
buf[stream_ptr]);
260 colors[5] =
LE_16(&
buf[stream_ptr]);
262 colors[6] =
LE_16(&
buf[stream_ptr]);
264 colors[7] =
LE_16(&
buf[stream_ptr]);
267 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
268 for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
270 colors[((pixel_y & 0x2) << 1) +
271 (pixel_x & 0x2) + ((
flags & 0x1) ^ 1)];
272 pixel_ptr -= row_dec;
276 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
277 for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
279 pixel_ptr -= row_dec;
284 colors[0] = (byte_b << 8) | byte_a;
286 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
287 for (pixel_x = 0; pixel_x < 4; pixel_x++)
288 pixels[pixel_ptr++] = colors[0];
289 pixel_ptr -= row_dec;
293 block_ptr += block_inc;
307 TRACE(
"in->planes = %d\n",
in->bmiHeader.biPlanes );
308 TRACE(
"in->bpp = %d\n",
in->bmiHeader.biBitCount );
309 TRACE(
"in->height = %d\n",
in->bmiHeader.biHeight );
310 TRACE(
"in->width = %d\n",
in->bmiHeader.biWidth );
311 TRACE(
"in->compr = 0x%x\n",
in->bmiHeader.biCompression );
317 TRACE(
"can't do 0x%x compression\n",
in->bmiHeader.biCompression);
321 if( (
in->bmiHeader.biBitCount != 16 ) &&
322 (
in->bmiHeader.biBitCount != 8 ) )
324 TRACE(
"can't do %d bpp\n",
in->bmiHeader.biBitCount );
331 TRACE(
"out->planes = %d\n",
out->bmiHeader.biPlanes );
332 TRACE(
"out->bpp = %d\n",
out->bmiHeader.biBitCount );
333 TRACE(
"out->height = %d\n",
out->bmiHeader.biHeight );
334 TRACE(
"out->width = %d\n",
out->bmiHeader.biWidth );
336 if ((
in->bmiHeader.biBitCount !=
out->bmiHeader.biBitCount) &&
337 (
in->bmiHeader.biBitCount != 16 ||
out->bmiHeader.biBitCount != 24))
339 TRACE(
"incompatible depth requested\n");
343 if((
in->bmiHeader.biPlanes !=
out->bmiHeader.biPlanes ) ||
344 (
in->bmiHeader.biHeight !=
out->bmiHeader.biHeight ) ||
345 (
in->bmiHeader.biWidth !=
out->bmiHeader.biWidth ))
347 TRACE(
"incompatible output requested\n");
366 size =
in->bmiHeader.biSize;
367 if (
in->bmiHeader.biBitCount <= 8)
370 if (
in->bmiHeader.biBitCount != 8 &&
in->bmiHeader.biBitCount != 16)
376 out->bmiHeader.biWidth =
in->bmiHeader.biWidth & ~1;
377 out->bmiHeader.biHeight =
in->bmiHeader.biHeight & ~1;
379 out->bmiHeader.biSizeImage =
in->bmiHeader.biHeight *
394 TRACE(
"bitmap is %d bpp\n",
in->bmiHeader.biBitCount);
395 if(
in->bmiHeader.biBitCount == 8 )
397 else if(
in->bmiHeader.biBitCount == 16 )
402 FIXME(
"Unsupported output format %i\n",
in->bmiHeader.biBitCount);
414 if (depth_in == 16 && out_hdr->
biBitCount == 24)
416 static const unsigned char convert_5to8[] =
418 0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a,
419 0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b,
420 0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd,
421 0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff,
427 char *out_row = output +
y * stride_out;
431 WORD pixel = *src_row++;
432 *out_row++ = convert_5to8[(pixel & 0x7c00u) >> 10];
433 *out_row++ = convert_5to8[(pixel & 0x03e0u) >> 5];
434 *out_row++ = convert_5to8[(pixel & 0x001fu)];
439 FIXME(
"Conversion from %d to %d bit unimplemented\n", depth_in, out_hdr->
biBitCount);
458 output = icd->lpOutput;
466 if (
info->depth == 8)
512 if (
info->depth == 8)
536 if (!icinfo)
return sizeof(
ICINFO);
566 TRACE(
"%ld %p %04x %08lx %08lx\n", dwDriverId, hdrvr,
msg, lParam1, lParam2);
621 FIXME(
"ICM_DECOMPRESS_GET_PALETTE\n");
625 FIXME(
"ICM_DECOMPRESSEX_QUERY\n");
653 FIXME(
"compression not implemented\n");
660 FIXME(
"Unknown message: %04x %ld %ld\n",
msg, lParam1, lParam2);
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
#define DLL_PROCESS_ATTACH
#define HeapFree(x, y, z)
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
GLint GLint GLsizei GLsizei GLsizei depth
GLint GLint GLint GLint GLint x
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
GLint GLint GLint GLint GLint GLint y
GLint GLint GLsizei GLsizei height
GLdouble GLdouble GLdouble r
GLint GLint GLsizei width
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLenum GLenum input
#define memcpy(s1, s2, n)
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
static void msvideo1_decode_16bit(int width, int height, const unsigned char *buf, int buf_size, unsigned short *pixels, int stride)
static int get_stride(int width, int depth)
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
LRESULT WINAPI CRAM_DriverProc(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, LPARAM lParam1, LPARAM lParam2)
static LRESULT CRAM_Decompress(Msvideo1Context *info, ICDECOMPRESS *icd, DWORD size)
static LRESULT CRAM_DecompressEx(Msvideo1Context *info, ICDECOMPRESSEX *icd, DWORD size)
#define CHECK_STREAM_PTR(n)
static LRESULT CRAM_DecompressQuery(Msvideo1Context *info, LPBITMAPINFO in, LPBITMAPINFO out)
static void msvideo1_decode_8bit(int width, int height, const unsigned char *buf, int buf_size, unsigned char *pixels, int stride)
static LRESULT CRAM_GetInfo(const Msvideo1Context *info, ICINFO *icinfo, DWORD dwSize)
static void convert_depth(char *input, int depth_in, char *output, BITMAPINFOHEADER *out_hdr)
static LRESULT CRAM_DecompressBegin(Msvideo1Context *info, LPBITMAPINFO in, LPBITMAPINFO out)
#define compare_fourcc(fcc1, fcc2)
static LRESULT CRAM_DecompressGetFormat(Msvideo1Context *info, LPBITMAPINFO in, LPBITMAPINFO out)
static HINSTANCE MSVIDC32_hModule
LPBITMAPINFOHEADER lpbiSrc
LPBITMAPINFOHEADER lpbiDst
LPBITMAPINFOHEADER lpbiInput
LPBITMAPINFOHEADER lpbiOutput
#define ICM_COMPRESS_QUERY
#define ICM_DECOMPRESS_GET_PALETTE
#define ICM_DECOMPRESS_QUERY
#define ICERR_UNSUPPORTED
#define ICM_DECOMPRESS_GET_FORMAT
#define ICM_DECOMPRESS_END
#define ICM_DECOMPRESSEX_QUERY
#define ICM_COMPRESS_GET_FORMAT
#define ICM_DECOMPRESS_BEGIN
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)