ReactOS 0.4.15-dev-5896-g3f5bcf5
msrle32.c
Go to the documentation of this file.
1/*
2 * Copyright 2002-2003 Michael G├╝nnewig
3 *
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.
8 *
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.
13 *
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
17 */
18
19/* TODO:
20 * - some improvements possible
21 * - implement DecompressSetPalette? -- do we need it for anything?
22 */
23
24#include <assert.h>
25
26#include "msrle_private.h"
27
28#include "winnls.h"
29#include "winuser.h"
30
31#include "wine/debug.h"
32
34
36
37#define compare_fourcc(fcc1, fcc2) (((fcc1)^(fcc2))&~0x20202020)
38
39static inline WORD ColorCmp(WORD clr1, WORD clr2)
40{
41 UINT a = clr1 - clr2;
42 return a * a;
43}
44static inline WORD Intensity(RGBQUAD clr)
45{
46 return (30 * clr.rgbRed + 59 * clr.rgbGreen + 11 * clr.rgbBlue)/4;
47}
48
49#define GetRawPixel(lpbi,lp,x) \
50 ((lpbi)->biBitCount == 1 ? ((lp)[(x)/8] >> (8 - (x)%8)) & 1 : \
51 ((lpbi)->biBitCount == 4 ? ((lp)[(x)/2] >> (4 * (1 - (x)%2))) & 15 : lp[x]))
52
53/*****************************************************************************/
54
55/* utility functions */
59
60/* compression functions */
61static void computeInternalFrame(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, const BYTE *lpIn);
64 const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut,
65 LPBYTE lpOut, BOOL isKey);
67 const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut,
68 LPBYTE lpOut, BOOL isKey);
69
70/* decompression functions */
72 const BYTE *lpIn, LPBYTE lpOut);
74 const BYTE *lpIn, LPBYTE lpOut);
75
76/* API functions */
78 LPBITMAPINFOHEADER lpbiOut);
80 LPCBITMAPINFOHEADER lpbiOut);
82 LPCBITMAPINFOHEADER lpbiOut);
84 LPCBITMAPINFOHEADER lpbiOut);
87
89 LPBITMAPINFOHEADER lpbiOut);
91 LPCBITMAPINFOHEADER lpbiOut);
93 LPCBITMAPINFOHEADER lpbiOut);
97 LPBITMAPINFOHEADER lpbiOut);
98
99/*****************************************************************************/
100
102{
103 /* pre-conditions */
104 assert(lpbi != NULL);
105
106 if (lpbi->biSize < sizeof(BITMAPINFOHEADER) ||
107 lpbi->biPlanes != 1)
108 return FALSE;
109
110 if (lpbi->biCompression == BI_RLE4) {
111 if (lpbi->biBitCount != 4 ||
112 (lpbi->biWidth % 2) != 0)
113 return FALSE;
114 } else if (lpbi->biCompression == BI_RLE8) {
115 if (lpbi->biBitCount != 8)
116 return FALSE;
117 } else
118 return FALSE;
119
120 return TRUE;
121}
122
124{
125 /* pre-conditions */
126 assert(lpbi != NULL);
127
128 /* check structure version/planes/compression */
129 if (lpbi->biSize < sizeof(BITMAPINFOHEADER) ||
130 lpbi->biPlanes != 1)
131 return FALSE;
132 if (lpbi->biCompression != BI_RGB &&
134 return FALSE;
135
136 /* check bit-depth */
137 if (lpbi->biBitCount != 1 &&
138 lpbi->biBitCount != 4 &&
139 lpbi->biBitCount != 8 &&
140 lpbi->biBitCount != 15 &&
141 lpbi->biBitCount != 16 &&
142 lpbi->biBitCount != 24 &&
143 lpbi->biBitCount != 32)
144 return FALSE;
145
146 /* check for size(s) */
147 if (!lpbi->biWidth || !lpbi->biHeight)
148 return FALSE; /* image with zero size, makes no sense so error ! */
149 if (DIBWIDTHBYTES(*lpbi) * (DWORD)lpbi->biHeight >= (1UL << 31) - 1)
150 return FALSE; /* image too big ! */
151
152 /* check for nonexistent colortable for hi- and true-color DIB's */
153 if (lpbi->biBitCount >= 15 && lpbi->biClrUsed > 0)
154 return FALSE;
155
156 return TRUE;
157}
158
160{
161 INT diff = 0x00FFFFFF;
162 UINT i;
163 UINT idx = 0;
164
165 /* pre-conditions */
166 assert(clrs != NULL);
167
168 for (i = 0; i < count; i++) {
169 int r = ((int)clrs[i].rgbRed - (int)clr.rgbRed);
170 int g = ((int)clrs[i].rgbGreen - (int)clr.rgbGreen);
171 int b = ((int)clrs[i].rgbBlue - (int)clr.rgbBlue);
172
173 r = r*r + g*g + b*b;
174
175 if (r < diff) {
176 idx = i;
177 diff = r;
178 if (diff == 0)
179 break;
180 }
181 }
182
183 return idx;
184}
185
186/*****************************************************************************/
187
189{
190 WORD wIntensityTbl[256];
191 DWORD lInLine, lOutLine;
192 LPWORD lpOut;
193 UINT i;
194 LONG y;
195
196 /* pre-conditions */
197 assert(pi != NULL && lpbiIn != NULL && lpIn != NULL);
198 assert(pi->pCurFrame != NULL);
199
200 lInLine = DIBWIDTHBYTES(*lpbiIn);
201 lOutLine = WIDTHBYTES((WORD)lpbiIn->biWidth * 8u * sizeof(WORD)) / 2u;
202 lpOut = pi->pCurFrame;
203
204 assert(lpbiIn->biClrUsed != 0);
205
206 {
207 const RGBQUAD *lp =
208 (const RGBQUAD *)((const BYTE*)lpbiIn + lpbiIn->biSize);
209
210 for (i = 0; i < lpbiIn->biClrUsed; i++)
211 wIntensityTbl[i] = Intensity(lp[i]);
212 }
213
214 for (y = 0; y < lpbiIn->biHeight; y++) {
215 LONG x;
216
217 switch (lpbiIn->biBitCount) {
218 case 1:
219 for (x = 0; x < lpbiIn->biWidth / 8; x++) {
220 for (i = 0; i < 7; i++)
221 lpOut[8 * x + i] = wIntensityTbl[(lpIn[x] >> (7 - i)) & 1];
222 }
223 break;
224 case 4:
225 for (x = 0; x < lpbiIn->biWidth / 2; x++) {
226 lpOut[2 * x + 0] = wIntensityTbl[(lpIn[x] >> 4)];
227 lpOut[2 * x + 1] = wIntensityTbl[(lpIn[x] & 0x0F)];
228 }
229 break;
230 case 8:
231 for (x = 0; x < lpbiIn->biWidth; x++)
232 lpOut[x] = wIntensityTbl[lpIn[x]];
233 break;
234 }
235
236 lpIn += lInLine;
237 lpOut += lOutLine;
238 }
239}
240
242{
243 LONG a, b, size;
244
245 /* pre-condition */
246 assert(lpbi != NULL);
247
248 a = lpbi->biWidth / 255;
249 b = lpbi->biWidth % 255;
250 if (lpbi->biBitCount <= 4) {
251 a /= 2;
252 b /= 2;
253 }
254
255 size = (2 + a * (2 + ((a + 2) & ~2)) + b * (2 + ((b + 2) & ~2)));
256 return size * lpbi->biHeight + 2;
257}
258
259/* lpP => current pos in previous frame
260 * lpA => previous pos in current frame
261 * lpB => current pos in current frame
262 */
263static INT countDiffRLE4(const WORD *lpP, const WORD *lpA, const WORD *lpB, INT pos, LONG lDist, LONG width)
264{
265 INT count;
266 WORD clr1, clr2;
267
268 /* pre-conditions */
269 assert(lpA && lpB && lDist >= 0 && width > 0);
270
271 if (pos >= width)
272 return 0;
273 if (pos+1 == width)
274 return 1;
275
276 clr1 = lpB[pos++];
277 clr2 = lpB[pos];
278
279 count = 2;
280 while (pos + 1 < width) {
281 WORD clr3, clr4;
282
283 clr3 = lpB[++pos];
284 if (pos + 1 >= width)
285 return count + 1;
286
287 clr4 = lpB[++pos];
288 if (ColorCmp(clr1, clr3) <= lDist &&
289 ColorCmp(clr2, clr4) <= lDist) {
290 /* diff at end? -- look-ahead for at least ?? more encodable pixels */
291 if (pos + 2 < width && ColorCmp(clr1,lpB[pos+1]) <= lDist &&
292 ColorCmp(clr2,lpB[pos+2]) <= lDist) {
293 if (pos + 4 < width && ColorCmp(lpB[pos+1],lpB[pos+3]) <= lDist &&
294 ColorCmp(lpB[pos+2],lpB[pos+4]) <= lDist)
295 return count - 3; /* followed by at least 4 encodable pixels */
296 return count - 2;
297 }
298 } else if (lpP != NULL && ColorCmp(lpP[pos], lpB[pos]) <= lDist) {
299 /* 'compare' with previous frame for end of diff */
300 INT count2 = 0;
301
302 /* FIXME */
303
304 if (count2 >= 8)
305 return count;
306
307 pos -= count2;
308 }
309
310 count += 2;
311 clr1 = clr3;
312 clr2 = clr4;
313 }
314
315 return count;
316}
317
318/* lpP => current pos in previous frame
319 * lpA => previous pos in current frame
320 * lpB => current pos in current frame
321 */
322static INT countDiffRLE8(const WORD *lpP, const WORD *lpA, const WORD *lpB, INT pos, LONG lDist, LONG width)
323{
324 INT count;
325
326 for (count = 0; pos < width; pos++, count++) {
327 if (ColorCmp(lpA[pos], lpB[pos]) <= lDist) {
328 /* diff at end? -- look-ahead for some more encodable pixel */
329 if (pos + 1 < width && ColorCmp(lpB[pos], lpB[pos+1]) <= lDist)
330 return count - 1;
331 if (pos + 2 < width && ColorCmp(lpB[pos+1], lpB[pos+2]) <= lDist)
332 return count - 1;
333 } else if (lpP != NULL && ColorCmp(lpP[pos], lpB[pos]) <= lDist) {
334 /* 'compare' with previous frame for end of diff */
335 INT count2 = 0;
336
337 for (count2 = 0, pos++; pos < width && count2 <= 5; pos++, count2++) {
338 if (ColorCmp(lpP[pos], lpB[pos]) > lDist)
339 break;
340 }
341 if (count2 > 4)
342 return count;
343
344 pos -= count2;
345 }
346 }
347
348 return count;
349}
350
351static INT MSRLE32_CompressRLE4Line(const CodecInfo *pi, const WORD *lpP,
352 const WORD *lpC, LPCBITMAPINFOHEADER lpbi,
353 const BYTE *lpIn, LONG lDist,
354 INT x, LPBYTE *ppOut,
355 DWORD *lpSizeImage)
356{
357 LPBYTE lpOut = *ppOut;
358 INT count, pos;
359 WORD clr1, clr2;
360
361 /* try to encode as many pixel as possible */
362 count = 1;
363 pos = x;
364 clr1 = lpC[pos++];
365 if (pos < lpbi->biWidth) {
366 clr2 = lpC[pos];
367 for (++count; pos + 1 < lpbi->biWidth; ) {
368 ++pos;
369 if (ColorCmp(clr1, lpC[pos]) > lDist)
370 break;
371 count++;
372 if (pos + 1 >= lpbi->biWidth)
373 break;
374 ++pos;
375 if (ColorCmp(clr2, lpC[pos]) > lDist)
376 break;
377 count++;
378 }
379 }
380
381 if (count < 4) {
382 /* add some pixel for absoluting if possible */
383 count += countDiffRLE4(lpP, lpC - 1, lpC, pos-1, lDist, lpbi->biWidth);
384
385 assert(count > 0);
386
387 /* check for near end of line */
388 if (x + count > lpbi->biWidth)
389 count = lpbi->biWidth - x;
390
391 /* absolute pixel(s) in groups of at least 3 and at most 254 pixels */
392 while (count > 2) {
393 INT i;
394 INT size = min(count, 254);
395 int bytes = ((size + 1) & (~1)) / 2;
396 int extra_byte = bytes & 0x01;
397
398 *lpSizeImage += 2 + bytes + extra_byte;
399 assert(((*lpSizeImage) % 2) == 0);
400 count -= size;
401 *lpOut++ = 0;
402 *lpOut++ = size;
403 for (i = 0; i < size; i += 2) {
404 clr1 = pi->palette_map[GetRawPixel(lpbi,lpIn,x)];
405 x++;
406 if (i + 1 < size) {
407 clr2 = pi->palette_map[GetRawPixel(lpbi,lpIn,x)];
408 x++;
409 } else
410 clr2 = 0;
411
412 *lpOut++ = (clr1 << 4) | clr2;
413 }
414 if (extra_byte)
415 *lpOut++ = 0;
416 }
417
418 if (count > 0) {
419 /* too little for absoluting so we must encode them */
420 assert(count <= 2);
421
422 *lpSizeImage += 2;
423 clr1 = pi->palette_map[GetRawPixel(lpbi,lpIn,x)];
424 x++;
425 if (count == 2) {
426 clr2 = pi->palette_map[GetRawPixel(lpbi,lpIn,x)];
427 x++;
428 } else
429 clr2 = 0;
430 *lpOut++ = count;
431 *lpOut++ = (clr1 << 4) | clr2;
432 }
433 } else {
434 /* encode count pixel(s) */
435 clr1 = ((pi->palette_map[GetRawPixel(lpbi,lpIn,x)] << 4) |
436 pi->palette_map[GetRawPixel(lpbi,lpIn,x + 1)]);
437
438 x += count;
439 while (count > 0) {
440 INT size = min(count, 254);
441
442 *lpSizeImage += 2;
443 count -= size;
444 *lpOut++ = size;
445 *lpOut++ = clr1;
446 }
447 }
448
449 *ppOut = lpOut;
450
451 return x;
452}
453
454static INT MSRLE32_CompressRLE8Line(const CodecInfo *pi, const WORD *lpP,
455 const WORD *lpC, LPCBITMAPINFOHEADER lpbi,
456 const BYTE *lpIn, INT x, LPBYTE *ppOut,
457 DWORD *lpSizeImage)
458{
459 LPBYTE lpOut = *ppOut;
460 INT count, pos;
461 WORD clr;
462
463 assert(lpbi->biBitCount <= 8);
464 assert(lpbi->biCompression == BI_RGB);
465
466 /* try to encode as much as possible */
467 pos = x;
468 clr = lpC[pos++];
469 for (count = 1; pos < lpbi->biWidth; count++) {
470 if (ColorCmp(clr, lpC[pos++]) > 0)
471 break;
472 }
473
474 if (count < 2) {
475 /* add some more pixels for absoluting if possible */
476 count += countDiffRLE8(lpP, lpC - 1, lpC, pos-1, 0, lpbi->biWidth);
477
478 assert(count > 0);
479
480 /* check for over end of line */
481 if (x + count > lpbi->biWidth)
482 count = lpbi->biWidth - x;
483
484 /* absolute pixel(s) in groups of at least 3 and at most 255 pixels */
485 while (count > 2) {
486 INT i;
487 INT size = min(count, 255);
488 int extra_byte = size % 2;
489
490 *lpSizeImage += 2 + size + extra_byte;
491 count -= size;
492 *lpOut++ = 0;
493 *lpOut++ = size;
494 for (i = 0; i < size; i++) {
495 *lpOut++ = pi->palette_map[GetRawPixel(lpbi,lpIn,x)];
496 x++;
497 }
498 if (extra_byte)
499 *lpOut++ = 0;
500 }
501 if (count > 0) {
502 /* too little for absoluting so we must encode them even if it's expensive! */
503 assert(count <= 2);
504
505 *lpSizeImage += 2 * count;
506 *lpOut++ = 1;
507 *lpOut++ = pi->palette_map[GetRawPixel(lpbi,lpIn,x)];
508 x++;
509
510 if (count == 2) {
511 *lpOut++ = 1;
512 *lpOut++ = pi->palette_map[GetRawPixel(lpbi,lpIn,x)];
513 x++;
514 }
515 }
516 } else {
517 /* encode count pixel(s) */
518 clr = pi->palette_map[GetRawPixel(lpbi,lpIn,x)];
519
520 /* optimize end of line */
521 if (x + count + 1 == lpbi->biWidth)
522 count++;
523
524 x += count;
525 while (count > 0) {
526 INT size = min(count, 255);
527
528 *lpSizeImage += 2;
529 count -= size;
530 *lpOut++ = size;
531 *lpOut++ = clr;
532 }
533 }
534
535 *ppOut = lpOut;
536
537 return x;
538}
539
541 const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut,
542 LPBYTE lpOut, BOOL isKey)
543{
544 LPWORD lpC;
545 LONG lLine, lInLine;
546 LPBYTE lpOutStart = lpOut;
547
548 /* pre-conditions */
549 assert(pi != NULL && lpbiOut != NULL);
550 assert(lpIn != NULL && lpOut != NULL);
551 assert(pi->pCurFrame != NULL);
552
553 lpC = pi->pCurFrame;
554 lInLine = DIBWIDTHBYTES(*lpbiIn);
555 lLine = WIDTHBYTES(lpbiOut->biWidth * 16) / 2;
556
557 lpbiOut->biSizeImage = 0;
558 if (isKey) {
559 /* keyframe -- convert internal frame to output format */
560 INT x, y;
561
562 for (y = 0; y < lpbiOut->biHeight; y++) {
563 x = 0;
564
565 do {
566 x = MSRLE32_CompressRLE4Line(pi, NULL, lpC, lpbiIn, lpIn, 0, x,
567 &lpOut, &lpbiOut->biSizeImage);
568 } while (x < lpbiOut->biWidth);
569
570 lpC += lLine;
571 lpIn += lInLine;
572
573 /* add EOL -- end of line */
574 lpbiOut->biSizeImage += 2;
575 *(LPWORD)lpOut = 0;
576 lpOut += sizeof(WORD);
577 assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
578 }
579 } else {
580 /* delta-frame -- compute delta between last and this internal frame */
581 LPWORD lpP;
582 INT x, y;
583 INT jumpx, jumpy;
584
585 assert(pi->pPrevFrame != NULL);
586
587 lpP = pi->pPrevFrame;
588 jumpy = 0;
589 jumpx = -1;
590
591 for (y = 0; y < lpbiOut->biHeight; y++) {
592 x = 0;
593
594 do {
595 INT count, pos;
596
597 if (jumpx == -1)
598 jumpx = x;
599 for (count = 0, pos = x; pos < lpbiOut->biWidth; pos++, count++) {
600 if (ColorCmp(lpP[pos], lpC[pos]) > 0)
601 break;
602 }
603
604 if (pos == lpbiOut->biWidth && count > 8) {
605 /* (count > 8) secures that we will save space */
606 jumpy++;
607 break;
608 } else if (jumpy || jumpx != pos) {
609 /* time to jump */
610 assert(jumpx != -1);
611
612 if (pos < jumpx) {
613 /* can only jump in positive direction -- jump until EOL, EOL */
614 INT w = lpbiOut->biWidth - jumpx;
615
616 assert(jumpy > 0);
617 assert(w >= 4);
618
619 jumpx = 0;
620 jumpy--;
621 /* if (w % 255 == 2) then equal costs
622 * else if (w % 255 < 4 && we could encode all) then 2 bytes too expensive
623 * else it will be cheaper
624 */
625 while (w > 0) {
626 lpbiOut->biSizeImage += 4;
627 *lpOut++ = 0;
628 *lpOut++ = 2;
629 *lpOut = min(w, 255);
630 w -= *lpOut++;
631 *lpOut++ = 0;
632 }
633 /* add EOL -- end of line */
634 lpbiOut->biSizeImage += 2;
635 *((LPWORD)lpOut) = 0;
636 lpOut += sizeof(WORD);
637 }
638
639 /* FIXME: if (jumpy == 0 && could encode all) then jump too expensive */
640
641 /* write out real jump(s) */
642 while (jumpy || pos != jumpx) {
643 lpbiOut->biSizeImage += 4;
644 *lpOut++ = 0;
645 *lpOut++ = 2;
646 *lpOut = min(pos - jumpx, 255);
647 x += *lpOut;
648 jumpx += *lpOut++;
649 *lpOut = min(jumpy, 255);
650 jumpy -= *lpOut++;
651 }
652
653 jumpy = 0;
654 }
655
656 jumpx = -1;
657
658 if (x < lpbiOut->biWidth) {
659 /* skipped the 'same' things corresponding to previous frame */
660 x = MSRLE32_CompressRLE4Line(pi, lpP, lpC, lpbiIn, lpIn, 0, x,
661 &lpOut, &lpbiOut->biSizeImage);
662 }
663 } while (x < lpbiOut->biWidth);
664
665 lpP += lLine;
666 lpC += lLine;
667 lpIn += lInLine;
668
669 if (jumpy == 0) {
670 assert(jumpx == -1);
671
672 /* add EOL -- end of line */
673 lpbiOut->biSizeImage += 2;
674 *((LPWORD)lpOut) = 0;
675 lpOut += sizeof(WORD);
676 assert(lpOut == lpOutStart + lpbiOut->biSizeImage);
677 }
678 }
679
680 /* add EOL -- will be changed to EOI */
681 lpbiOut->biSizeImage += 2;
682 *((LPWORD)lpOut) = 0;
683 lpOut += sizeof(WORD);
684 }
685
686 /* change EOL to EOI -- end of image */
687 lpOut[-1] = 1;
688 assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
689
690 return ICERR_OK;
691}
692
694 const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut,
695 LPBYTE lpOut, BOOL isKey)
696{
697 LPWORD lpC;
698 LONG lInLine, lLine;
699 LPBYTE lpOutStart = lpOut;
700
701 assert(pi != NULL && lpbiOut != NULL);
702 assert(lpIn != NULL && lpOut != NULL);
703 assert(pi->pCurFrame != NULL);
704
705 lpC = pi->pCurFrame;
706 lInLine = DIBWIDTHBYTES(*lpbiIn);
707 lLine = WIDTHBYTES(lpbiOut->biWidth * 16) / 2;
708
709 lpbiOut->biSizeImage = 0;
710 if (isKey) {
711 /* keyframe -- convert internal frame to output format */
712 INT x, y;
713
714 for (y = 0; y < lpbiOut->biHeight; y++) {
715 x = 0;
716
717 do {
718 x = MSRLE32_CompressRLE8Line(pi, NULL, lpC, lpbiIn, lpIn, x,
719 &lpOut, &lpbiOut->biSizeImage);
720 assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
721 } while (x < lpbiOut->biWidth);
722
723 lpC += lLine;
724 lpIn += lInLine;
725
726 /* add EOL -- end of line */
727 lpbiOut->biSizeImage += 2;
728 *((LPWORD)lpOut) = 0;
729 lpOut += sizeof(WORD);
730 assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
731 }
732 } else {
733 /* delta-frame -- compute delta between last and this internal frame */
734 LPWORD lpP;
735 INT x, y;
736 INT jumpx, jumpy;
737
738 assert(pi->pPrevFrame != NULL);
739
740 lpP = pi->pPrevFrame;
741 jumpx = -1;
742 jumpy = 0;
743
744 for (y = 0; y < lpbiOut->biHeight; y++) {
745 x = 0;
746
747 do {
748 INT count, pos;
749
750 if (jumpx == -1)
751 jumpx = x;
752 for (count = 0, pos = x; pos < lpbiOut->biWidth; pos++, count++) {
753 if (ColorCmp(lpP[pos], lpC[pos]) > 0)
754 break;
755 }
756
757 if (pos == lpbiOut->biWidth && count > 4) {
758 /* (count > 4) secures that we will save space */
759 jumpy++;
760 break;
761 } else if (jumpy || jumpx != pos) {
762 /* time to jump */
763 assert(jumpx != -1);
764
765 if (pos < jumpx) {
766 /* can only jump in positive direction -- do an EOL then jump */
767 assert(jumpy > 0);
768
769 jumpx = 0;
770 jumpy--;
771
772 /* add EOL -- end of line */
773 lpbiOut->biSizeImage += 2;
774 *((LPWORD)lpOut) = 0;
775 lpOut += sizeof(WORD);
776 assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
777 }
778
779 /* FIXME: if (jumpy == 0 && could encode all) then jump too expensive */
780
781 /* write out real jump(s) */
782 while (jumpy || pos != jumpx) {
783 lpbiOut->biSizeImage += 4;
784 *lpOut++ = 0;
785 *lpOut++ = 2;
786 *lpOut = min(pos - jumpx, 255);
787 jumpx += *lpOut++;
788 *lpOut = min(jumpy, 255);
789 jumpy -= *lpOut++;
790 }
791 x = pos;
792
793 jumpy = 0;
794 }
795
796 jumpx = -1;
797
798 if (x < lpbiOut->biWidth) {
799 /* skip the 'same' things corresponding to previous frame */
800 x = MSRLE32_CompressRLE8Line(pi, lpP, lpC, lpbiIn, lpIn, x,
801 &lpOut, &lpbiOut->biSizeImage);
802 assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
803 }
804 } while (x < lpbiOut->biWidth);
805
806 lpP += lLine;
807 lpC += lLine;
808 lpIn += lInLine;
809
810 if (jumpy == 0) {
811 /* add EOL -- end of line */
812 lpbiOut->biSizeImage += 2;
813 *((LPWORD)lpOut) = 0;
814 lpOut += sizeof(WORD);
815 assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
816 }
817 }
818
819 /* add EOL */
820 lpbiOut->biSizeImage += 2;
821 *((LPWORD)lpOut) = 0;
822 lpOut += sizeof(WORD);
823 }
824
825 /* add EOI -- end of image */
826 lpbiOut->biSizeImage += 2;
827 *lpOut++ = 0;
828 *lpOut++ = 1;
829 assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
830
831 return ICERR_OK;
832}
833
834/*****************************************************************************/
835
837 const BYTE *lpIn, LPBYTE lpOut)
838{
839 int bytes_per_pixel;
840 int line_size;
841 int pixel_ptr = 0;
842 int i;
843 BOOL bEndFlag = FALSE;
844
845 assert(pi != NULL);
846 assert(lpbi != NULL && lpbi->biCompression == BI_RGB);
847 assert(lpIn != NULL && lpOut != NULL);
848
849 bytes_per_pixel = (lpbi->biBitCount + 1) / 8;
850 line_size = DIBWIDTHBYTES(*lpbi);
851
852 do {
853 BYTE code0, code1;
854
855 code0 = *lpIn++;
856 code1 = *lpIn++;
857
858 if (code0 == 0) {
859 int extra_byte;
860
861 switch (code1) {
862 case 0: /* EOL - end of line */
863 pixel_ptr = 0;
864 lpOut += line_size;
865 break;
866 case 1: /* EOI - end of image */
867 bEndFlag = TRUE;
868 break;
869 case 2: /* skip */
870 pixel_ptr += *lpIn++ * bytes_per_pixel;
871 lpOut += *lpIn++ * line_size;
872 if (pixel_ptr >= lpbi->biWidth * bytes_per_pixel) {
873 pixel_ptr = 0;
874 lpOut += line_size;
875 }
876 break;
877 default: /* absolute mode */
878 extra_byte = (((code1 + 1) & (~1)) / 2) & 0x01;
879
880 if (pixel_ptr/bytes_per_pixel + code1 > lpbi->biWidth)
881 return ICERR_ERROR;
882
883 code0 = code1;
884 for (i = 0; i < code0 / 2; i++) {
885 if (bytes_per_pixel == 1) {
886 code1 = lpIn[i];
887 lpOut[pixel_ptr++] = pi->palette_map[(code1 >> 4)];
888 if (2 * i + 1 <= code0)
889 lpOut[pixel_ptr++] = pi->palette_map[(code1 & 0x0F)];
890 } else if (bytes_per_pixel == 2) {
891 code1 = lpIn[i] >> 4;
892 lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0];
893 lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1];
894
895 if (2 * i + 1 <= code0) {
896 code1 = lpIn[i] & 0x0F;
897 lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0];
898 lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1];
899 }
900 } else {
901 code1 = lpIn[i] >> 4;
902 lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0];
903 lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1];
904 lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2];
905 pixel_ptr += bytes_per_pixel;
906
907 if (2 * i + 1 <= code0) {
908 code1 = lpIn[i] & 0x0F;
909 lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0];
910 lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1];
911 lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2];
912 pixel_ptr += bytes_per_pixel;
913 }
914 }
915 }
916 if (code0 & 0x01) {
917 if (bytes_per_pixel == 1) {
918 code1 = lpIn[i];
919 lpOut[pixel_ptr++] = pi->palette_map[(code1 >> 4)];
920 } else if (bytes_per_pixel == 2) {
921 code1 = lpIn[i] >> 4;
922 lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0];
923 lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1];
924 } else {
925 code1 = lpIn[i] >> 4;
926 lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0];
927 lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1];
928 lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2];
929 pixel_ptr += bytes_per_pixel;
930 }
931 lpIn++;
932 }
933 lpIn += code0 / 2;
934
935 /* if the RLE code is odd, skip a byte in the stream */
936 if (extra_byte)
937 lpIn++;
938 };
939 } else {
940 /* coded mode */
941 if (pixel_ptr/bytes_per_pixel + code0 > lpbi->biWidth)
942 return ICERR_ERROR;
943
944 if (bytes_per_pixel == 1) {
945 BYTE c1 = pi->palette_map[(code1 >> 4)];
946 BYTE c2 = pi->palette_map[(code1 & 0x0F)];
947
948 for (i = 0; i < code0; i++) {
949 if ((i & 1) == 0)
950 lpOut[pixel_ptr++] = c1;
951 else
952 lpOut[pixel_ptr++] = c2;
953 }
954 } else if (bytes_per_pixel == 2) {
955 BYTE hi1 = pi->palette_map[(code1 >> 4) * 2 + 0];
956 BYTE lo1 = pi->palette_map[(code1 >> 4) * 2 + 1];
957
958 BYTE hi2 = pi->palette_map[(code1 & 0x0F) * 2 + 0];
959 BYTE lo2 = pi->palette_map[(code1 & 0x0F) * 2 + 1];
960
961 for (i = 0; i < code0; i++) {
962 if ((i & 1) == 0) {
963 lpOut[pixel_ptr++] = hi1;
964 lpOut[pixel_ptr++] = lo1;
965 } else {
966 lpOut[pixel_ptr++] = hi2;
967 lpOut[pixel_ptr++] = lo2;
968 }
969 }
970 } else {
971 BYTE b1 = pi->palette_map[(code1 >> 4) * 4 + 0];
972 BYTE g1 = pi->palette_map[(code1 >> 4) * 4 + 1];
973 BYTE r1 = pi->palette_map[(code1 >> 4) * 4 + 2];
974
975 BYTE b2 = pi->palette_map[(code1 & 0x0F) * 4 + 0];
976 BYTE g2 = pi->palette_map[(code1 & 0x0F) * 4 + 1];
977 BYTE r2 = pi->palette_map[(code1 & 0x0F) * 4 + 2];
978
979 for (i = 0; i < code0; i++) {
980 if ((i & 1) == 0) {
981 lpOut[pixel_ptr + 0] = b1;
982 lpOut[pixel_ptr + 1] = g1;
983 lpOut[pixel_ptr + 2] = r1;
984 } else {
985 lpOut[pixel_ptr + 0] = b2;
986 lpOut[pixel_ptr + 1] = g2;
987 lpOut[pixel_ptr + 2] = r2;
988 }
989 pixel_ptr += bytes_per_pixel;
990 }
991 }
992 }
993 } while (! bEndFlag);
994
995 return ICERR_OK;
996}
997
999 const BYTE *lpIn, LPBYTE lpOut)
1000{
1001 int bytes_per_pixel;
1002 int line_size;
1003 int pixel_ptr = 0;
1004 BOOL bEndFlag = FALSE;
1005
1006 assert(pi != NULL);
1007 assert(lpbi != NULL && lpbi->biCompression == BI_RGB);
1008 assert(lpIn != NULL && lpOut != NULL);
1009
1010 bytes_per_pixel = (lpbi->biBitCount + 1) / 8;
1011 line_size = DIBWIDTHBYTES(*lpbi);
1012
1013 do {
1014 BYTE code0, code1;
1015
1016 code0 = *lpIn++;
1017 code1 = *lpIn++;
1018
1019 if (code0 == 0) {
1020 int extra_byte;
1021
1022 switch (code1) {
1023 case 0: /* EOL - end of line */
1024 pixel_ptr = 0;
1025 lpOut += line_size;
1026 break;
1027 case 1: /* EOI - end of image */
1028 bEndFlag = TRUE;
1029 break;
1030 case 2: /* skip */
1031 pixel_ptr += *lpIn++ * bytes_per_pixel;
1032 lpOut += *lpIn++ * line_size;
1033 if (pixel_ptr >= lpbi->biWidth * bytes_per_pixel) {
1034 pixel_ptr = 0;
1035 lpOut += line_size;
1036 }
1037 break;
1038 default: /* absolute mode */
1039 if (pixel_ptr/bytes_per_pixel + code1 > lpbi->biWidth) {
1040 WARN("aborted absolute: (%d=%d/%d+%d) > %d\n",pixel_ptr/bytes_per_pixel + code1,pixel_ptr,bytes_per_pixel,code1,lpbi->biWidth);
1041 return ICERR_ERROR;
1042 }
1043 extra_byte = code1 & 0x01;
1044
1045 code0 = code1;
1046 while (code0--) {
1047 code1 = *lpIn++;
1048 if (bytes_per_pixel == 1) {
1049 lpOut[pixel_ptr] = pi->palette_map[code1];
1050 } else if (bytes_per_pixel == 2) {
1051 lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 2 + 0];
1052 lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 2 + 1];
1053 } else {
1054 lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0];
1055 lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1];
1056 lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2];
1057 }
1058 pixel_ptr += bytes_per_pixel;
1059 }
1060
1061 /* if the RLE code is odd, skip a byte in the stream */
1062 if (extra_byte)
1063 lpIn++;
1064 };
1065 } else {
1066 /* coded mode */
1067 if (pixel_ptr/bytes_per_pixel + code0 > lpbi->biWidth) {
1068 WARN("aborted coded: (%d=%d/%d+%d) > %d\n",pixel_ptr/bytes_per_pixel + code1,pixel_ptr,bytes_per_pixel,code1,lpbi->biWidth);
1069 return ICERR_ERROR;
1070 }
1071
1072 if (bytes_per_pixel == 1) {
1073 code1 = pi->palette_map[code1];
1074 while (code0--)
1075 lpOut[pixel_ptr++] = code1;
1076 } else if (bytes_per_pixel == 2) {
1077 BYTE hi = pi->palette_map[code1 * 2 + 0];
1078 BYTE lo = pi->palette_map[code1 * 2 + 1];
1079
1080 while (code0--) {
1081 lpOut[pixel_ptr + 0] = hi;
1082 lpOut[pixel_ptr + 1] = lo;
1083 pixel_ptr += bytes_per_pixel;
1084 }
1085 } else {
1086 BYTE r = pi->palette_map[code1 * 4 + 2];
1087 BYTE g = pi->palette_map[code1 * 4 + 1];
1088 BYTE b = pi->palette_map[code1 * 4 + 0];
1089
1090 while (code0--) {
1091 lpOut[pixel_ptr + 0] = b;
1092 lpOut[pixel_ptr + 1] = g;
1093 lpOut[pixel_ptr + 2] = r;
1094 pixel_ptr += bytes_per_pixel;
1095 }
1096 }
1097 }
1098 } while (! bEndFlag);
1099
1100 return ICERR_OK;
1101}
1102
1103/*****************************************************************************/
1104
1105static CodecInfo* Open(LPICOPEN icinfo)
1106{
1107 CodecInfo* pi = NULL;
1108
1109 if (icinfo == NULL) {
1110 TRACE("(NULL)\n");
1111 return (LPVOID)0xFFFF0000;
1112 }
1113
1114 if (compare_fourcc(icinfo->fccType, ICTYPE_VIDEO)) return NULL;
1115
1116 TRACE("(%p = {%u,0x%08X(%4.4s),0x%08X(%4.4s),0x%X,0x%X,...})\n", icinfo,
1117 icinfo->dwSize, icinfo->fccType, (char*)&icinfo->fccType,
1118 icinfo->fccHandler, (char*)&icinfo->fccHandler,
1119 icinfo->dwVersion,icinfo->dwFlags);
1120
1121 switch (icinfo->fccHandler) {
1122 case FOURCC_RLE:
1123 case FOURCC_RLE4:
1124 case FOURCC_RLE8:
1125 case FOURCC_MRLE:
1126 break;
1127 case mmioFOURCC('m','r','l','e'):
1128 icinfo->fccHandler = FOURCC_MRLE;
1129 break;
1130 default:
1131 WARN("unknown FOURCC = 0x%08X(%4.4s) !\n",
1132 icinfo->fccHandler,(char*)&icinfo->fccHandler);
1133 return NULL;
1134 }
1135
1136 pi = LocalAlloc(LPTR, sizeof(CodecInfo));
1137
1138 if (pi != NULL) {
1139 pi->fccHandler = icinfo->fccHandler;
1140
1141 pi->bCompress = FALSE;
1142 pi->nPrevFrame = -1;
1143 pi->pPrevFrame = pi->pCurFrame = NULL;
1144
1145 pi->bDecompress = FALSE;
1146 pi->palette_map = NULL;
1147 }
1148
1149 icinfo->dwError = (pi != NULL ? ICERR_OK : ICERR_MEMORY);
1150
1151 return pi;
1152}
1153
1155{
1156 TRACE("(%p)\n", pi);
1157
1158 /* pre-condition */
1159 assert(pi != NULL);
1160
1161 if (pi->pPrevFrame != NULL || pi->pCurFrame != NULL)
1162 CompressEnd(pi);
1163
1164 LocalFree(pi);
1165 return 1;
1166}
1167
1169{
1170 /* pre-condition */
1171 assert(pi != NULL);
1172
1173 /* check parameters */
1174 if (icinfo == NULL)
1175 return sizeof(ICINFO);
1176 if (dwSize < sizeof(ICINFO))
1177 return 0;
1178
1179 icinfo->dwSize = sizeof(ICINFO);
1180 icinfo->fccType = ICTYPE_VIDEO;
1181 icinfo->fccHandler = (pi != NULL ? pi->fccHandler : FOURCC_MRLE);
1183 icinfo->dwVersion = ICVERSION;
1184 icinfo->dwVersionICM = ICVERSION;
1185
1188
1189 return sizeof(ICINFO);
1190}
1191
1193{
1194 /* pre-condition */
1195 assert(pi != NULL);
1196
1197 /* FIXME */
1198 return ICERR_OK;
1199}
1200
1202{
1203 WCHAR szTitle[20];
1204 WCHAR szAbout[128];
1205
1206 /* pre-condition */
1207 assert(MSRLE32_hModule != 0);
1208
1210 LoadStringW(MSRLE32_hModule, IDS_ABOUT, szAbout, ARRAY_SIZE(szAbout));
1211
1213
1214 return ICERR_OK;
1215}
1216
1218 LPBITMAPINFOHEADER lpbiOut)
1219{
1220 LRESULT size;
1221
1222 TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
1223
1224 /* pre-condition */
1225 assert(pi != NULL);
1226
1227 /* check parameters -- need at least input format */
1228 if (lpbiIn == NULL) {
1229 if (lpbiOut != NULL)
1230 return ICERR_BADPARAM;
1231 return 0;
1232 }
1233
1234 /* handle unsupported input format */
1235 if (CompressQuery(pi, lpbiIn, NULL) != ICERR_OK)
1236 return (lpbiOut == NULL ? ICERR_BADFORMAT : 0);
1237
1238 assert(0 < lpbiIn->biBitCount && lpbiIn->biBitCount <= 8);
1239
1240 switch (pi->fccHandler) {
1241 case FOURCC_RLE4:
1242 size = 1 << 4;
1243 break;
1244 case FOURCC_RLE8:
1245 size = 1 << 8;
1246 break;
1247 case FOURCC_RLE:
1248 case FOURCC_MRLE:
1249 size = (lpbiIn->biBitCount <= 4 ? 1 << 4 : 1 << 8);
1250 break;
1251 default:
1252 return ICERR_ERROR;
1253 }
1254
1255 if (lpbiIn->biClrUsed != 0)
1256 size = lpbiIn->biClrUsed;
1257
1258 size = sizeof(BITMAPINFOHEADER) + size * sizeof(RGBQUAD);
1259
1260 if (lpbiOut != NULL) {
1261 lpbiOut->biSize = sizeof(BITMAPINFOHEADER);
1262 lpbiOut->biWidth = lpbiIn->biWidth;
1263 lpbiOut->biHeight = lpbiIn->biHeight;
1264 lpbiOut->biPlanes = 1;
1265 if (pi->fccHandler == FOURCC_RLE4 ||
1266 lpbiIn->biBitCount <= 4) {
1267 lpbiOut->biCompression = BI_RLE4;
1268 lpbiOut->biBitCount = 4;
1269 } else {
1270 lpbiOut->biCompression = BI_RLE8;
1271 lpbiOut->biBitCount = 8;
1272 }
1273 lpbiOut->biSizeImage = MSRLE32_GetMaxCompressedSize(lpbiOut);
1274 lpbiOut->biXPelsPerMeter = lpbiIn->biXPelsPerMeter;
1275 lpbiOut->biYPelsPerMeter = lpbiIn->biYPelsPerMeter;
1276 if (lpbiIn->biClrUsed == 0)
1277 size = 1<<lpbiIn->biBitCount;
1278 else
1279 size = lpbiIn->biClrUsed;
1280 lpbiOut->biClrUsed = min(size, 1 << lpbiOut->biBitCount);
1281 lpbiOut->biClrImportant = 0;
1282
1283 memcpy((LPBYTE)lpbiOut + lpbiOut->biSize,
1284 (const BYTE*)lpbiIn + lpbiIn->biSize, lpbiOut->biClrUsed * sizeof(RGBQUAD));
1285
1286 return ICERR_OK;
1287 } else
1288 return size;
1289}
1290
1292 LPCBITMAPINFOHEADER lpbiOut)
1293{
1294 /* pre-condition */
1295 assert(pi != NULL);
1296
1297 TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
1298
1299 /* check parameter -- need at least one format */
1300 if (lpbiIn == NULL && lpbiOut == NULL)
1301 return 0;
1302 /* check if the given format is supported */
1303 if (CompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK)
1304 return 0;
1305
1306 /* the worst case is coding the complete image in absolute mode. */
1307 if (lpbiIn)
1308 return MSRLE32_GetMaxCompressedSize(lpbiIn);
1309 else
1310 return MSRLE32_GetMaxCompressedSize(lpbiOut);
1311}
1312
1314 LPCBITMAPINFOHEADER lpbiOut)
1315{
1316 /* pre-condition */
1317 assert(pi != NULL);
1318
1319 /* need at least one format */
1320 if (lpbiIn == NULL && lpbiOut == NULL)
1321 return ICERR_BADPARAM;
1322
1323 /* check input format if given */
1324 if (lpbiIn != NULL) {
1325 if (!isSupportedDIB(lpbiIn))
1326 return ICERR_BADFORMAT;
1327
1328 /* for 4-bit need an even width */
1329 if (lpbiIn->biBitCount <= 4 && (lpbiIn->biWidth % 2))
1330 return ICERR_BADFORMAT;
1331
1332 if (pi->fccHandler == FOURCC_RLE4 && lpbiIn->biBitCount > 4)
1333 return ICERR_UNSUPPORTED;
1334 else if (lpbiIn->biBitCount > 8)
1335 return ICERR_UNSUPPORTED;
1336 }
1337
1338 /* check output format if given */
1339 if (lpbiOut != NULL) {
1340 if (!isSupportedMRLE(lpbiOut))
1341 return ICERR_BADFORMAT;
1342
1343 if (lpbiIn != NULL) {
1344 if (lpbiIn->biWidth != lpbiOut->biWidth)
1345 return ICERR_UNSUPPORTED;
1346 if (lpbiIn->biHeight != lpbiOut->biHeight)
1347 return ICERR_UNSUPPORTED;
1348 if (lpbiIn->biBitCount > lpbiOut->biBitCount)
1349 return ICERR_UNSUPPORTED;
1350 }
1351 }
1352
1353 return ICERR_OK;
1354}
1355
1357 LPCBITMAPINFOHEADER lpbiOut)
1358{
1359 const RGBQUAD *rgbIn;
1360 const RGBQUAD *rgbOut;
1361 UINT i;
1362 size_t size;
1363
1364 TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
1365
1366 /* pre-condition */
1367 assert(pi != NULL);
1368
1369 /* check parameters -- need both formats */
1370 if (lpbiIn == NULL || lpbiOut == NULL)
1371 return ICERR_BADPARAM;
1372 /* And both must be supported */
1373 if (CompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK)
1374 return ICERR_BADFORMAT;
1375
1376 /* FIXME: cannot compress and decompress at same time! */
1377 if (pi->bDecompress) {
1378 FIXME("cannot compress and decompress at same time!\n");
1379 return ICERR_ERROR;
1380 }
1381
1382 if (pi->bCompress)
1383 CompressEnd(pi);
1384
1385 size = WIDTHBYTES(lpbiOut->biWidth * 16) / 2 * lpbiOut->biHeight;
1386 pi->pPrevFrame = GlobalLock(GlobalAlloc(GPTR, size * sizeof(WORD)));
1387 if (pi->pPrevFrame == NULL)
1388 return ICERR_MEMORY;
1389 pi->pCurFrame = GlobalLock(GlobalAlloc(GPTR, size * sizeof(WORD)));
1390 if (pi->pCurFrame == NULL) {
1391 CompressEnd(pi);
1392 return ICERR_MEMORY;
1393 }
1394 pi->nPrevFrame = -1;
1395 pi->bCompress = TRUE;
1396
1397 rgbIn = (const RGBQUAD*)((const BYTE*)lpbiIn + lpbiIn->biSize);
1398 rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize);
1399
1400 switch (lpbiOut->biBitCount) {
1401 case 4:
1402 case 8:
1403 pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed);
1404 if (pi->palette_map == NULL) {
1405 CompressEnd(pi);
1406 return ICERR_MEMORY;
1407 }
1408
1409 for (i = 0; i < lpbiIn->biClrUsed; i++) {
1410 pi->palette_map[i] = MSRLE32_GetNearestPaletteIndex(lpbiOut->biClrUsed, rgbOut, rgbIn[i]);
1411 }
1412 break;
1413 };
1414
1415 return ICERR_OK;
1416}
1417
1419{
1420 BOOL is_key;
1421 int i;
1422
1423 TRACE("(%p,%p,%u)\n",pi,lpic,dwSize);
1424
1425 /* pre-condition */
1426 assert(pi != NULL);
1427
1428 /* check parameters */
1429 if (lpic == NULL || dwSize < sizeof(ICCOMPRESS))
1430 return ICERR_BADPARAM;
1431 if (!lpic->lpbiOutput || !lpic->lpOutput ||
1432 !lpic->lpbiInput || !lpic->lpInput)
1433 return ICERR_BADPARAM;
1434
1435 TRACE("lpic={0x%X,%p,%p,%p,%p,%p,%p,%d,%u,%u,%p,%p}\n",lpic->dwFlags,lpic->lpbiOutput,lpic->lpOutput,lpic->lpbiInput,lpic->lpInput,lpic->lpckid,lpic->lpdwFlags,lpic->lFrameNum,lpic->dwFrameSize,lpic->dwQuality,lpic->lpbiPrev,lpic->lpPrev);
1436
1437 if (! pi->bCompress) {
1438 LRESULT hr = CompressBegin(pi, lpic->lpbiInput, lpic->lpbiOutput);
1439 if (hr != ICERR_OK)
1440 return hr;
1441 } else if (CompressQuery(pi, lpic->lpbiInput, lpic->lpbiOutput) != ICERR_OK)
1442 return ICERR_BADFORMAT;
1443
1444 if (lpic->lFrameNum >= pi->nPrevFrame + 1) {
1445 /* we continue in the sequence so we need to initialize
1446 * our internal framedata */
1447
1448 computeInternalFrame(pi, lpic->lpbiInput, lpic->lpInput);
1449 } else if (lpic->lFrameNum == pi->nPrevFrame) {
1450 /* Oops, compress same frame again ? Okay, as you wish.
1451 * No need to recompute internal framedata, because we only swapped buffers */
1452 LPWORD pTmp = pi->pPrevFrame;
1453
1454 pi->pPrevFrame = pi->pCurFrame;
1455 pi->pCurFrame = pTmp;
1456 } else if ((lpic->dwFlags & ICCOMPRESS_KEYFRAME) == 0) {
1457 LPWORD pTmp;
1458
1459 WARN(": prev=%d cur=%d gone back? -- untested\n",pi->nPrevFrame,lpic->lFrameNum);
1460 if (lpic->lpbiPrev == NULL || lpic->lpPrev == NULL)
1461 return ICERR_GOTOKEYFRAME; /* Need a keyframe if you go back */
1462 if (CompressQuery(pi, lpic->lpbiPrev, lpic->lpbiOutput) != ICERR_OK)
1463 return ICERR_BADFORMAT;
1464
1465 WARN(": prev=%d cur=%d compute swapped -- untested\n",pi->nPrevFrame,lpic->lFrameNum);
1466 computeInternalFrame(pi, lpic->lpbiPrev, lpic->lpPrev);
1467
1468 /* swap buffers for current and previous frame */
1469 /* Don't free and alloc new -- costs too much time and they are of equal size ! */
1470 pTmp = pi->pPrevFrame;
1471 pi->pPrevFrame = pi->pCurFrame;
1472 pi->pCurFrame = pTmp;
1473 pi->nPrevFrame = lpic->lFrameNum;
1474 }
1475
1476 is_key = (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0;
1477
1478 for (i = 0; i < 3; i++) {
1479 lpic->lpbiOutput->biSizeImage = 0;
1480
1481 if (lpic->lpbiOutput->biBitCount == 4)
1482 MSRLE32_CompressRLE4(pi, lpic->lpbiInput, lpic->lpInput, lpic->lpbiOutput, lpic->lpOutput, is_key);
1483 else
1484 MSRLE32_CompressRLE8(pi, lpic->lpbiInput, lpic->lpInput, lpic->lpbiOutput, lpic->lpOutput, is_key);
1485
1486 if (lpic->dwFrameSize == 0 ||
1487 lpic->lpbiOutput->biSizeImage < lpic->dwFrameSize)
1488 break;
1489
1490 if ((*lpic->lpdwFlags & ICCOMPRESS_KEYFRAME) == 0) {
1491 if (lpic->lpbiOutput->biBitCount == 4)
1492 MSRLE32_CompressRLE4(pi, lpic->lpbiInput, lpic->lpInput,
1493 lpic->lpbiOutput, lpic->lpOutput, TRUE);
1494 else
1495 MSRLE32_CompressRLE8(pi, lpic->lpbiInput, lpic->lpInput,
1496 lpic->lpbiOutput, lpic->lpOutput, TRUE);
1497
1498 if (lpic->dwFrameSize == 0 ||
1499 lpic->lpbiOutput->biSizeImage < lpic->dwFrameSize) {
1500 WARN("switched to keyframe, was small enough!\n");
1501 is_key = TRUE;
1503 StreamFromFOURCC(*lpic->lpckid));
1504 break;
1505 }
1506 }
1507
1508 if (lpic->dwQuality < 1000)
1509 break;
1510
1511 lpic->dwQuality -= 1000; /* reduce quality by 10% */
1512 }
1513
1514 { /* swap buffer for current and previous frame */
1515 /* Don't free and alloc new -- costs too much time and they are of equal size ! */
1516 LPWORD pTmp = pi->pPrevFrame;
1517
1518 pi->pPrevFrame = pi->pCurFrame;
1519 pi->pCurFrame = pTmp;
1520 pi->nPrevFrame = lpic->lFrameNum;
1521 }
1522
1523 /* FIXME: What is AVIIF_TWOCC? */
1524 *lpic->lpdwFlags |= AVIIF_TWOCC | (is_key ? AVIIF_KEYFRAME : 0);
1525 return ICERR_OK;
1526}
1527
1529{
1530 TRACE("(%p)\n",pi);
1531
1532 if (pi != NULL) {
1533 if (pi->pPrevFrame != NULL)
1534 {
1535 GlobalUnlock(GlobalHandle(pi->pPrevFrame));
1536 GlobalFree(GlobalHandle(pi->pPrevFrame));
1537 }
1538 if (pi->pCurFrame != NULL)
1539 {
1540 GlobalUnlock(GlobalHandle(pi->pCurFrame));
1541 GlobalFree(GlobalHandle(pi->pCurFrame));
1542 }
1543 pi->pPrevFrame = NULL;
1544 pi->pCurFrame = NULL;
1545 pi->nPrevFrame = -1;
1546 pi->bCompress = FALSE;
1547
1548 if (pi->palette_map != NULL) {
1549 LocalFree(pi->palette_map);
1550 pi->palette_map = NULL;
1551 }
1552 }
1553
1554 return ICERR_OK;
1555}
1556
1558 LPBITMAPINFOHEADER lpbiOut)
1559{
1560 DWORD size;
1561
1562 TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
1563
1564 /* pre-condition */
1565 assert(pi != NULL);
1566
1567 if (lpbiIn == NULL)
1568 return (lpbiOut != NULL ? ICERR_BADPARAM : 0);
1569
1570 if (DecompressQuery(pi, lpbiIn, NULL) != ICERR_OK)
1571 return (lpbiOut != NULL ? ICERR_BADFORMAT : 0);
1572
1573 size = lpbiIn->biSize;
1574
1575 if (lpbiIn->biBitCount <= 8) {
1576 int colors;
1577
1578 if (lpbiIn->biClrUsed == 0)
1579 colors = 1 << lpbiIn->biBitCount;
1580 else
1581 colors = lpbiIn->biClrUsed;
1582
1583 size += colors * sizeof(RGBQUAD);
1584 }
1585
1586 if (lpbiOut != NULL) {
1587 memcpy(lpbiOut, lpbiIn, size);
1588 lpbiOut->biCompression = BI_RGB;
1589 lpbiOut->biSizeImage = DIBWIDTHBYTES(*lpbiOut) * lpbiOut->biHeight;
1590
1591 return ICERR_OK;
1592 } else
1593 return size;
1594}
1595
1597 LPCBITMAPINFOHEADER lpbiOut)
1598{
1600
1601 TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
1602
1603 /* pre-condition */
1604 assert(pi != NULL);
1605
1606 /* need at least one format */
1607 if (lpbiIn == NULL && lpbiOut == NULL)
1608 return ICERR_BADPARAM;
1609
1610 /* check input format if given */
1611 if (lpbiIn != NULL) {
1612 if (!isSupportedMRLE(lpbiIn) && !isSupportedDIB(lpbiIn))
1613 return ICERR_BADFORMAT;
1614 }
1615
1616 /* check output format if given */
1617 if (lpbiOut != NULL) {
1618 if (!isSupportedDIB(lpbiOut))
1620
1621 if (lpbiIn != NULL) {
1622 if (lpbiIn->biWidth != lpbiOut->biWidth)
1624 if (lpbiIn->biHeight != lpbiOut->biHeight)
1626 if (lpbiIn->biBitCount > lpbiOut->biBitCount)
1628 }
1629 }
1630
1631 return hr;
1632}
1633
1635 LPCBITMAPINFOHEADER lpbiOut)
1636{
1637 const RGBQUAD *rgbIn;
1638 const RGBQUAD *rgbOut;
1639 UINT i;
1640
1641 TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
1642
1643 /* pre-condition */
1644 assert(pi != NULL);
1645
1646 /* check parameters */
1647 if (lpbiIn == NULL || lpbiOut == NULL)
1648 return ICERR_BADPARAM;
1649 if (DecompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK)
1650 return ICERR_BADFORMAT;
1651
1652 /* FIXME: cannot compress and decompress at a time! */
1653 if (pi->bCompress) {
1654 FIXME("cannot compress and decompress at same time!\n");
1655 return ICERR_ERROR;
1656 }
1657
1658 if (pi->bDecompress)
1660
1661 if (lpbiIn->biCompression != BI_RGB)
1662 {
1663 int colors;
1664
1665 if (lpbiIn->biBitCount <= 8 && lpbiIn->biClrUsed == 0)
1666 colors = 1 << lpbiIn->biBitCount;
1667 else
1668 colors = lpbiIn->biClrUsed;
1669
1670 rgbIn = (const RGBQUAD*)((const BYTE*)lpbiIn + lpbiIn->biSize);
1671 rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize);
1672
1673 switch (lpbiOut->biBitCount) {
1674 case 4:
1675 case 8:
1676 pi->palette_map = LocalAlloc(LPTR, colors);
1677 if (pi->palette_map == NULL)
1678 return ICERR_MEMORY;
1679
1680 for (i = 0; i < colors; i++)
1681 pi->palette_map[i] = MSRLE32_GetNearestPaletteIndex(colors, rgbOut, rgbIn[i]);
1682 break;
1683 case 15:
1684 case 16:
1685 pi->palette_map = LocalAlloc(LPTR, colors * 2);
1686 if (pi->palette_map == NULL)
1687 return ICERR_MEMORY;
1688
1689 for (i = 0; i < colors; i++) {
1690 WORD color;
1691
1692 if (lpbiOut->biBitCount == 15)
1693 color = ((rgbIn[i].rgbRed >> 3) << 10)
1694 | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3);
1695 else
1696 color = ((rgbIn[i].rgbRed >> 3) << 11)
1697 | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3);
1698
1699 pi->palette_map[i * 2 + 1] = color >> 8;
1700 pi->palette_map[i * 2 + 0] = color & 0xFF;
1701 };
1702 break;
1703 case 24:
1704 case 32:
1705 pi->palette_map = LocalAlloc(LPTR, colors * sizeof(RGBQUAD));
1706 if (pi->palette_map == NULL)
1707 return ICERR_MEMORY;
1708 memcpy(pi->palette_map, rgbIn, colors * sizeof(RGBQUAD));
1709 break;
1710 };
1711 }
1712 pi->bDecompress = TRUE;
1713
1714 return ICERR_OK;
1715}
1716
1718{
1719 TRACE("(%p,%p,%u)\n",pi,pic,dwSize);
1720
1721 /* pre-condition */
1722 assert(pi != NULL);
1723
1724 /* check parameters */
1725 if (pic == NULL)
1726 return ICERR_BADPARAM;
1727 if (pic->lpbiInput == NULL || pic->lpInput == NULL ||
1728 pic->lpbiOutput == NULL || pic->lpOutput == NULL)
1729 return ICERR_BADPARAM;
1730
1731 /* check formats */
1732 if (! pi->bDecompress) {
1734 if (hr != ICERR_OK)
1735 return hr;
1736 } else if (DecompressQuery(pi, pic->lpbiInput, pic->lpbiOutput) != ICERR_OK)
1737 return ICERR_BADFORMAT;
1738
1739 assert(pic->lpbiInput->biWidth == pic->lpbiOutput->biWidth);
1741
1742 /* Uncompressed frame? */
1743 if (pic->lpbiInput->biCompression == BI_RGB)
1744 {
1746 memcpy(pic->lpOutput, pic->lpInput, pic->lpbiOutput->biSizeImage);
1747 return ICERR_OK;
1748 }
1749
1751 if (pic->lpbiInput->biBitCount == 4)
1752 return MSRLE32_DecompressRLE4(pi, pic->lpbiOutput, pic->lpInput, pic->lpOutput);
1753 else
1754 return MSRLE32_DecompressRLE8(pi, pic->lpbiOutput, pic->lpInput, pic->lpOutput);
1755}
1756
1758{
1759 TRACE("(%p)\n",pi);
1760
1761 /* pre-condition */
1762 assert(pi != NULL);
1763
1764 pi->bDecompress = FALSE;
1765
1766 if (pi->palette_map != NULL) {
1767 LocalFree(pi->palette_map);
1768 pi->palette_map = NULL;
1769 }
1770
1771 return ICERR_OK;
1772}
1773
1775 LPBITMAPINFOHEADER lpbiOut)
1776{
1777 int size;
1778
1779 TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
1780
1781 /* pre-condition */
1782 assert(pi != NULL);
1783
1784 /* check parameters */
1785 if (lpbiIn == NULL || lpbiOut == NULL)
1786 return ICERR_BADPARAM;
1787
1788 if (DecompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK)
1789 return ICERR_BADFORMAT;
1790
1791 if (lpbiOut->biBitCount > 8)
1792 return ICERR_ERROR;
1793
1794 if (lpbiIn->biBitCount <= 8) {
1795 if (lpbiIn->biClrUsed > 0)
1796 size = lpbiIn->biClrUsed;
1797 else
1798 size = (1 << lpbiIn->biBitCount);
1799
1800 lpbiOut->biClrUsed = size;
1801
1802 memcpy((LPBYTE)lpbiOut + lpbiOut->biSize, (const BYTE*)lpbiIn + lpbiIn->biSize, size * sizeof(RGBQUAD));
1803 } /* else could never occur ! */
1804
1805 return ICERR_OK;
1806}
1807
1808/* DriverProc - entry point for an installable driver */
1810 LPARAM lParam1, LPARAM lParam2)
1811{
1812 CodecInfo *pi = (CodecInfo*)dwDrvID;
1813
1814 TRACE("(%lx,%p,0x%04X,0x%08lX,0x%08lX)\n", dwDrvID, hDrv, uMsg, lParam1, lParam2);
1815
1816 switch (uMsg) {
1817 /* standard driver messages */
1818 case DRV_LOAD:
1819 return DRVCNF_OK;
1820 case DRV_OPEN:
1821 return (LRESULT)Open((ICOPEN*)lParam2);
1822 case DRV_CLOSE:
1823 if (dwDrvID != 0xFFFF0000 && (LPVOID)dwDrvID != NULL)
1824 Close(pi);
1825 return DRVCNF_OK;
1826 case DRV_ENABLE:
1827 case DRV_DISABLE:
1828 return DRVCNF_OK;
1829 case DRV_FREE:
1830 return DRVCNF_OK;
1831 case DRV_QUERYCONFIGURE:
1832 return DRVCNF_CANCEL; /* FIXME */
1833 case DRV_CONFIGURE:
1834 return DRVCNF_OK; /* FIXME */
1835 case DRV_INSTALL:
1836 case DRV_REMOVE:
1837 return DRVCNF_OK;
1838
1839 /* installable compression manager messages */
1840 case ICM_CONFIGURE:
1841 FIXME("ICM_CONFIGURE (%ld)\n",lParam1);
1842 if (lParam1 == -1)
1843 return ICERR_UNSUPPORTED; /* FIXME */
1844 else
1845 return Configure(pi, (HWND)lParam1);
1846 case ICM_ABOUT:
1847 if (lParam1 == -1)
1848 return ICERR_OK;
1849 else
1850 return About(pi, (HWND)lParam1);
1851 case ICM_GETSTATE:
1852 case ICM_SETSTATE:
1853 return 0; /* no state */
1854 case ICM_GETINFO:
1855 return GetInfo(pi, (ICINFO*)lParam1, (DWORD)lParam2);
1857 if ((LPVOID)lParam1 != NULL) {
1858 *((LPDWORD)lParam1) = MSRLE32_DEFAULTQUALITY;
1859 return ICERR_OK;
1860 }
1861 break;
1863 return CompressGetFormat(pi, (LPCBITMAPINFOHEADER)lParam1,
1864 (LPBITMAPINFOHEADER)lParam2);
1866 return CompressGetSize(pi, (LPCBITMAPINFOHEADER)lParam1,
1867 (LPCBITMAPINFOHEADER)lParam2);
1868 case ICM_COMPRESS_QUERY:
1869 return CompressQuery(pi, (LPCBITMAPINFOHEADER)lParam1,
1870 (LPCBITMAPINFOHEADER)lParam2);
1871 case ICM_COMPRESS_BEGIN:
1872 return CompressBegin(pi, (LPCBITMAPINFOHEADER)lParam1,
1873 (LPCBITMAPINFOHEADER)lParam2);
1874 case ICM_COMPRESS:
1875 return Compress(pi, (ICCOMPRESS*)lParam1, (DWORD)lParam2);
1876 case ICM_COMPRESS_END:
1877 return CompressEnd(pi);
1880 (LPBITMAPINFOHEADER)lParam2);
1882 return DecompressQuery(pi, (LPCBITMAPINFOHEADER)lParam1,
1883 (LPCBITMAPINFOHEADER)lParam2);
1885 return DecompressBegin(pi, (LPCBITMAPINFOHEADER)lParam1,
1886 (LPCBITMAPINFOHEADER)lParam2);
1887 case ICM_DECOMPRESS:
1888 return Decompress(pi, (ICDECOMPRESS*)lParam1, (DWORD)lParam2);
1889 case ICM_DECOMPRESS_END:
1890 return DecompressEnd(pi);
1892 FIXME("(...) -> SetPalette(%p,%p,%p): stub!\n", pi, (LPVOID)lParam1, (LPVOID)lParam2);
1893 return ICERR_UNSUPPORTED;
1896 (LPBITMAPINFOHEADER)lParam2);
1898 if ((LPVOID)lParam1 != NULL)
1899 *(LPDWORD)lParam1 = 15;
1900 return ICERR_OK;
1901 default:
1902 if (uMsg < DRV_USER)
1903 return DefDriverProc(dwDrvID, hDrv, uMsg, lParam1, lParam2);
1904 else
1905 FIXME("Unknown message uMsg=0x%08X lParam1=0x%08lX lParam2=0x%08lX\n",uMsg,lParam1,lParam2);
1906 };
1907
1908 return ICERR_UNSUPPORTED;
1909}
1910
1911/* DllMain - library initialization code */
1913{
1914 TRACE("(%p,%d,%p)\n",hModule,dwReason,lpReserved);
1915
1916 switch (dwReason) {
1917 case DLL_PROCESS_ATTACH:
1920 break;
1921 }
1922
1923 return TRUE;
1924}
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define DIBWIDTHBYTES(bi)
#define WIDTHBYTES(i)
#define AVIIF_KEYFRAME
Definition: aviriff.h:131
#define IDS_ABOUT
Definition: resource.h:29
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define IDS_DESCRIPTION
Definition: resource.h:4
#define ARRAY_SIZE(A)
Definition: main.h:33
DWORD dwReason
Definition: misc.cpp:154
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define IDS_NAME
Definition: resource.h:90
unsigned int idx
Definition: utils.c:41
HMODULE hModule
Definition: animate.c:44
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define CALLBACK
Definition: compat.h:35
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
#define assert(x)
Definition: debug.h:53
#define BI_RLE4
Definition: precomp.h:48
#define BI_RGB
Definition: precomp.h:47
ULONG RGBQUAD
Definition: precomp.h:50
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint color
Definition: glext.h:6243
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean g
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HGLOBAL NTAPI GlobalHandle(LPCVOID pMem)
Definition: heapmem.c:705
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define DRV_LOAD(x)
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
#define Open
Definition: syshdrs.h:62
TCHAR szTitle[MAX_LOADSTRING]
Definition: magnifier.c:35
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BI_BITFIELDS
Definition: mmreg.h:507
#define ICTYPE_VIDEO
Definition: mmreg.h:531
#define DRV_CLOSE
Definition: mmsystem.h:122
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define DRV_USER
Definition: mmsystem.h:132
#define DRVCNF_CANCEL
Definition: mmsystem.h:133
#define DRV_REMOVE
Definition: mmsystem.h:128
#define DRV_ENABLE
Definition: mmsystem.h:120
#define DRV_CONFIGURE
Definition: mmsystem.h:125
#define DRV_OPEN
Definition: mmsystem.h:121
#define DRVCNF_OK
Definition: mmsystem.h:134
#define DRV_INSTALL
Definition: mmsystem.h:127
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define DRV_FREE
Definition: mmsystem.h:124
#define DRV_DISABLE
Definition: mmsystem.h:123
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:582
static CRYPT_DATA_BLOB b1[]
Definition: msg.c:573
static DNS_RECORDW r1
Definition: record.c:37
static DNS_RECORDW r2
Definition: record.c:38
static refpint_t pi[]
Definition: server.c:96
#define min(a, b)
Definition: monoChain.cc:55
static LRESULT DecompressGetPalette(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
Definition: msrle32.c:1774
static BOOL isSupportedDIB(LPCBITMAPINFOHEADER lpbi)
Definition: msrle32.c:123
static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER lpbiOut)
Definition: msrle32.c:1356
static LRESULT Compress(CodecInfo *pi, ICCOMPRESS *lpic, DWORD dwSize)
Definition: msrle32.c:1418
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
Definition: msrle32.c:1912
static LRESULT Decompress(CodecInfo *pi, ICDECOMPRESS *pic, DWORD dwSize)
Definition: msrle32.c:1717
static LRESULT About(CodecInfo *pi, HWND hWnd)
Definition: msrle32.c:1201
static LRESULT CompressQuery(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER lpbiOut)
Definition: msrle32.c:1313
static LRESULT MSRLE32_CompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut, LPBYTE lpOut, BOOL isKey)
Definition: msrle32.c:693
#define GetRawPixel(lpbi, lp, x)
Definition: msrle32.c:49
static BYTE MSRLE32_GetNearestPaletteIndex(UINT count, const RGBQUAD *clrs, RGBQUAD clr)
Definition: msrle32.c:159
static LRESULT DecompressEnd(CodecInfo *pi)
Definition: msrle32.c:1757
static LRESULT MSRLE32_DecompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbi, const BYTE *lpIn, LPBYTE lpOut)
Definition: msrle32.c:836
LRESULT CALLBACK MSRLE32_DriverProc(DWORD_PTR dwDrvID, HDRVR hDrv, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
Definition: msrle32.c:1809
static LRESULT MSRLE32_DecompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbi, const BYTE *lpIn, LPBYTE lpOut)
Definition: msrle32.c:998
static LRESULT CompressEnd(CodecInfo *pi)
Definition: msrle32.c:1528
static LRESULT CompressGetFormat(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
Definition: msrle32.c:1217
static HINSTANCE MSRLE32_hModule
Definition: msrle32.c:35
static BOOL isSupportedMRLE(LPCBITMAPINFOHEADER lpbi)
Definition: msrle32.c:101
static WORD ColorCmp(WORD clr1, WORD clr2)
Definition: msrle32.c:39
#define compare_fourcc(fcc1, fcc2)
Definition: msrle32.c:37
static LRESULT CompressGetSize(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER lpbiOut)
Definition: msrle32.c:1291
static LRESULT DecompressGetFormat(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
Definition: msrle32.c:1557
static LONG MSRLE32_GetMaxCompressedSize(LPCBITMAPINFOHEADER lpbi)
Definition: msrle32.c:241
static INT MSRLE32_CompressRLE8Line(const CodecInfo *pi, const WORD *lpP, const WORD *lpC, LPCBITMAPINFOHEADER lpbi, const BYTE *lpIn, INT x, LPBYTE *ppOut, DWORD *lpSizeImage)
Definition: msrle32.c:454
static LRESULT DecompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER lpbiOut)
Definition: msrle32.c:1634
static void computeInternalFrame(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, const BYTE *lpIn)
Definition: msrle32.c:188
static INT MSRLE32_CompressRLE4Line(const CodecInfo *pi, const WORD *lpP, const WORD *lpC, LPCBITMAPINFOHEADER lpbi, const BYTE *lpIn, LONG lDist, INT x, LPBYTE *ppOut, DWORD *lpSizeImage)
Definition: msrle32.c:351
static LRESULT Configure(const CodecInfo *pi, HWND hWnd)
Definition: msrle32.c:1192
static INT countDiffRLE4(const WORD *lpP, const WORD *lpA, const WORD *lpB, INT pos, LONG lDist, LONG width)
Definition: msrle32.c:263
static WORD Intensity(RGBQUAD clr)
Definition: msrle32.c:44
static LRESULT MSRLE32_CompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut, LPBYTE lpOut, BOOL isKey)
Definition: msrle32.c:540
static LRESULT DecompressQuery(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER lpbiOut)
Definition: msrle32.c:1596
static INT countDiffRLE8(const WORD *lpP, const WORD *lpA, const WORD *lpB, INT pos, LONG lDist, LONG width)
Definition: msrle32.c:322
static LRESULT GetInfo(const CodecInfo *pi, ICINFO *icinfo, DWORD dwSize)
Definition: msrle32.c:1168
#define FOURCC_RLE8
Definition: msrle_private.h:41
#define FOURCC_RLE
Definition: msrle_private.h:39
#define MSRLE32_DEFAULTQUALITY
Definition: msrle_private.h:37
#define FOURCC_RLE4
Definition: msrle_private.h:40
#define FOURCC_MRLE
Definition: msrle_private.h:42
unsigned int UINT
Definition: ndis.h:50
#define LPDWORD
Definition: nt_native.h:46
long LONG
Definition: pedump.c:60
@ Close
Definition: sacdrv.h:268
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
LONG biYPelsPerMeter
Definition: amvideo.idl:38
DWORD biCompression
Definition: amvideo.idl:35
DWORD biClrImportant
Definition: amvideo.idl:40
LONG biXPelsPerMeter
Definition: amvideo.idl:37
DWORD biSizeImage
Definition: amvideo.idl:36
LPBITMAPINFOHEADER lpbiInput
Definition: vfw.h:176
LONG lFrameNum
Definition: vfw.h:180
DWORD dwFrameSize
Definition: vfw.h:181
DWORD dwQuality
Definition: vfw.h:182
LPBITMAPINFOHEADER lpbiPrev
Definition: vfw.h:183
DWORD dwFlags
Definition: vfw.h:173
LPBITMAPINFOHEADER lpbiOutput
Definition: vfw.h:174
LPDWORD lpdwFlags
Definition: vfw.h:179
LPDWORD lpckid
Definition: vfw.h:178
LPBITMAPINFOHEADER lpbiInput
Definition: vfw.h:335
LPBITMAPINFOHEADER lpbiOutput
Definition: vfw.h:337
Definition: vfw.h:280
DWORD dwSize
Definition: vfw.h:281
DWORD dwVersionICM
Definition: vfw.h:286
DWORD fccType
Definition: vfw.h:282
DWORD dwFlags
Definition: vfw.h:284
DWORD dwVersion
Definition: vfw.h:285
DWORD fccHandler
Definition: vfw.h:283
WCHAR szDescription[128]
Definition: vfw.h:291
WCHAR szName[16]
Definition: vfw.h:290
Definition: vfw.h:157
LRESULT dwError
Definition: vfw.h:163
DWORD dwSize
Definition: vfw.h:158
DWORD dwVersion
Definition: vfw.h:161
DWORD fccHandler
Definition: vfw.h:160
DWORD dwFlags
Definition: vfw.h:162
DWORD fccType
Definition: vfw.h:159
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWORD
Definition: typedefs.h:56
int32_t INT
Definition: typedefs.h:58
#define VIDCF_CRUNCH
Definition: vfw.h:298
#define ICM_COMPRESS_BEGIN
Definition: vfw.h:102
#define ICM_COMPRESS_GET_SIZE
Definition: vfw.h:100
#define ICM_GETDEFAULTKEYFRAMERATE
Definition: vfw.h:136
#define ICVERSION
Definition: vfw.h:45
#define ICERR_BADPARAM
Definition: vfw.h:61
#define ICERR_OK
Definition: vfw.h:50
#define VIDCF_QUALITY
Definition: vfw.h:297
#define ICM_COMPRESS_QUERY
Definition: vfw.h:101
#define ICM_DECOMPRESS_GET_PALETTE
Definition: vfw.h:112
#define ICM_DECOMPRESS_QUERY
Definition: vfw.h:107
#define ICERR_UNSUPPORTED
Definition: vfw.h:56
#define ICM_GETINFO
Definition: vfw.h:82
#define VIDCF_FASTTEMPORALC
Definition: vfw.h:302
#define ICERR_BADFORMAT
Definition: vfw.h:57
#define ICERR_ERROR
Definition: vfw.h:66
#define ICM_COMPRESS
Definition: vfw.h:103
#define ICM_GETSTATE
Definition: vfw.h:80
#define ICM_DECOMPRESS_GET_FORMAT
Definition: vfw.h:106
#define ICCOMPRESS_KEYFRAME
Definition: vfw.h:170
#define VIDCF_TEMPORAL
Definition: vfw.h:299
#define ICERR_GOTOKEYFRAME
Definition: vfw.h:53
#define ICM_CONFIGURE
Definition: vfw.h:84
#define ICM_DECOMPRESS_END
Definition: vfw.h:110
#define ICM_COMPRESS_GET_FORMAT
Definition: vfw.h:99
#define ICM_DECOMPRESS_BEGIN
Definition: vfw.h:108
#define MAKEAVICKID(tcc, stream)
Definition: vfw.h:923
#define ICERR_MEMORY
Definition: vfw.h:58
#define ICM_GETDEFAULTQUALITY
Definition: vfw.h:88
#define ICM_COMPRESS_END
Definition: vfw.h:104
#define ICM_SETSTATE
Definition: vfw.h:81
#define ICM_DECOMPRESS
Definition: vfw.h:109
#define cktypeDIBbits
Definition: vfw.h:910
#define AVIIF_TWOCC
Definition: vfw.h:977
#define StreamFromFOURCC(fcc)
Definition: vfw.h:919
#define ICM_ABOUT
Definition: vfw.h:85
#define ICM_DECOMPRESS_SET_PALETTE
Definition: vfw.h:111
#define LPTR
Definition: winbase.h:381
#define GPTR
Definition: winbase.h:296
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
#define WINAPI
Definition: msvc.h:6
#define BI_RLE8
Definition: wingdi.h:35
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_OK
Definition: winuser.h:784
#define MB_ICONINFORMATION
Definition: winuser.h:796
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193