20 #include <winpr/assert.h>
21 #include <winpr/cast.h>
23 #include <freerdp/config.h>
25 #include <freerdp/codec/bitmap.h>
26 #include <freerdp/codec/planar.h>
28 static INLINE UINT16 GETPIXEL16(
const void* WINPR_RESTRICT d, UINT32 x, UINT32 y, UINT32 w)
30 const BYTE* WINPR_RESTRICT src = (
const BYTE*)d + ((y * w + x) *
sizeof(UINT16));
31 return WINPR_ASSERTING_INT_CAST(UINT16, ((UINT16)src[1] << 8) | (UINT16)src[0]);
34 static INLINE UINT32 GETPIXEL32(
const void* WINPR_RESTRICT d, UINT32 x, UINT32 y, UINT32 w)
36 const BYTE* WINPR_RESTRICT src = (
const BYTE*)d + ((y * w + x) *
sizeof(UINT32));
37 return (((UINT32)src[3]) << 24) | (((UINT32)src[2]) << 16) | (((UINT32)src[1]) << 8) |
42 static INLINE UINT16 IN_PIXEL16(
const void* WINPR_RESTRICT in_ptr, UINT32 in_x, UINT32 in_y,
43 UINT32 in_w, UINT16 in_last_pixel)
48 return GETPIXEL16(in_ptr, in_x, in_y, in_w);
54 static INLINE UINT32 IN_PIXEL32(
const void* WINPR_RESTRICT in_ptr, UINT32 in_x, UINT32 in_y,
55 UINT32 in_w, UINT32 in_last_pixel)
60 return GETPIXEL32(in_ptr, in_x, in_y, in_w);
67 static INLINE UINT16 out_color_count_2(UINT16 in_count,
wStream* WINPR_RESTRICT in_s,
74 const BYTE temp = ((0x3 << 5) | in_count) & 0xFF;
75 Stream_Write_UINT8(in_s, temp);
77 else if (in_count < 256 + 32)
79 const BYTE temp = (in_count - 32) & 0xFF;
80 Stream_Write_UINT8(in_s, 0x60);
81 Stream_Write_UINT8(in_s, temp);
85 Stream_Write_UINT8(in_s, 0xf3);
86 Stream_Write_UINT16(in_s, in_count);
89 Stream_Write_UINT16(in_s, in_data);
94 #define OUT_COLOR_COUNT2(in_count, in_s, in_data) \
95 in_count = out_color_count_2(in_count, in_s, in_data)
99 static INLINE UINT16 out_color_count_3(UINT16 in_count,
wStream* WINPR_RESTRICT in_s,
106 const BYTE temp = ((0x3 << 5) | in_count) & 0xFF;
107 Stream_Write_UINT8(in_s, temp);
109 else if (in_count < 256 + 32)
111 const BYTE temp = (in_count - 32) & 0xFF;
112 Stream_Write_UINT8(in_s, 0x60);
113 Stream_Write_UINT8(in_s, temp);
117 Stream_Write_UINT8(in_s, 0xf3);
118 Stream_Write_UINT16(in_s, in_count);
121 Stream_Write_UINT8(in_s, in_data & 0xFF);
123 Stream_Write_UINT8(in_s, (in_data >> 8) & 0xFF);
124 Stream_Write_UINT8(in_s, (in_data >> 16) & 0xFF);
130 #define OUT_COLOR_COUNT3(in_count, in_s, in_data) \
131 in_count = out_color_count_3(in_count, in_s, in_data)
135 static INLINE UINT16 out_copy_count_2(UINT16 in_count,
wStream* WINPR_RESTRICT in_s,
136 wStream* WINPR_RESTRICT in_data)
143 const BYTE temp = ((0x4 << 5) | in_count) & 0xFF;
144 Stream_Write_UINT8(in_s, temp);
146 else if (in_count < 256 + 32)
148 const BYTE temp = (in_count - 32) & 0xFF;
149 Stream_Write_UINT8(in_s, 0x80);
150 Stream_Write_UINT8(in_s, temp);
154 Stream_Write_UINT8(in_s, 0xf4);
155 Stream_Write_UINT16(in_s, in_count);
158 Stream_Write(in_s, Stream_Buffer(in_data), 2ULL * in_count);
161 Stream_SetPosition(in_data, 0);
164 #define OUT_COPY_COUNT2(in_count, in_s, in_data) \
165 in_count = out_copy_count_2(in_count, in_s, in_data)
168 static INLINE UINT16 out_copy_count_3(UINT16 in_count,
wStream* WINPR_RESTRICT in_s,
169 wStream* WINPR_RESTRICT in_data)
175 const BYTE temp = ((0x4 << 5) | in_count) & 0xFF;
176 Stream_Write_UINT8(in_s, temp);
178 else if (in_count < 256 + 32)
180 const BYTE temp = (in_count - 32) & 0xFF;
181 Stream_Write_UINT8(in_s, 0x80);
182 Stream_Write_UINT8(in_s, temp);
186 Stream_Write_UINT8(in_s, 0xf4);
187 Stream_Write_UINT16(in_s, in_count);
190 Stream_Write(in_s, Stream_Pointer(in_data), 3ULL * in_count);
193 Stream_SetPosition(in_data, 0);
196 #define OUT_COPY_COUNT3(in_count, in_s, in_data) \
197 in_count = out_copy_count_3(in_count, in_s, in_data)
201 static INLINE UINT16 out_bicolor_count_2(UINT16 in_count,
wStream* WINPR_RESTRICT in_s,
202 UINT16 in_color1, UINT16 in_color2)
206 if (in_count / 2 < 16)
208 const BYTE temp = ((0xe << 4) | (in_count / 2)) & 0xFF;
209 Stream_Write_UINT8(in_s, temp);
211 else if (in_count / 2 < 256 + 16)
213 const BYTE temp = (in_count / 2 - 16) & 0xFF;
214 Stream_Write_UINT8(in_s, 0xe0);
215 Stream_Write_UINT8(in_s, temp);
219 Stream_Write_UINT8(in_s, 0xf8);
220 Stream_Write_UINT16(in_s, in_count / 2);
223 Stream_Write_UINT16(in_s, in_color1);
224 Stream_Write_UINT16(in_s, in_color2);
230 #define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \
231 in_count = out_bicolor_count_2(in_count, in_s, in_color1, in_color2)
235 static INLINE UINT16 out_bicolor_count_3(UINT16 in_count,
wStream* WINPR_RESTRICT in_s,
236 UINT32 in_color1, UINT32 in_color2)
240 if (in_count / 2 < 16)
242 const BYTE temp = ((0xe << 4) | (in_count / 2)) & 0xFF;
243 Stream_Write_UINT8(in_s, temp);
245 else if (in_count / 2 < 256 + 16)
247 const BYTE temp = (in_count / 2 - 16) & 0xFF;
248 Stream_Write_UINT8(in_s, 0xe0);
249 Stream_Write_UINT8(in_s, temp);
253 Stream_Write_UINT8(in_s, 0xf8);
254 Stream_Write_UINT16(in_s, in_count / 2);
257 Stream_Write_UINT8(in_s, in_color1 & 0xFF);
258 Stream_Write_UINT8(in_s, (in_color1 >> 8) & 0xFF);
259 Stream_Write_UINT8(in_s, (in_color1 >> 16) & 0xFF);
260 Stream_Write_UINT8(in_s, in_color2 & 0xFF);
261 Stream_Write_UINT8(in_s, (in_color2 >> 8) & 0xFF);
262 Stream_Write_UINT8(in_s, (in_color2 >> 16) & 0xFF);
268 #define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \
269 in_count = out_bicolor_count_3(in_count, in_s, in_color1, in_color2)
273 static INLINE UINT16 out_fill_count_2(UINT16 in_count,
wStream* WINPR_RESTRICT in_s)
279 Stream_Write_UINT8(in_s, in_count & 0xFF);
281 else if (in_count < 256 + 32)
283 const BYTE temp = (in_count - 32) & 0xFF;
284 Stream_Write_UINT8(in_s, 0x0);
285 Stream_Write_UINT8(in_s, temp);
289 Stream_Write_UINT8(in_s, 0xf0);
290 Stream_Write_UINT16(in_s, in_count);
297 #define OUT_FILL_COUNT2(in_count, in_s) in_count = out_fill_count_2(in_count, in_s)
301 static INLINE UINT16 out_fill_count_3(UINT16 in_count,
wStream* WINPR_RESTRICT in_s)
307 Stream_Write_UINT8(in_s, in_count & 0xFF);
309 else if (in_count < 256 + 32)
311 const BYTE temp = (in_count - 32) & 0xFF;
312 Stream_Write_UINT8(in_s, 0x0);
313 Stream_Write_UINT8(in_s, temp);
317 Stream_Write_UINT8(in_s, 0xf0);
318 Stream_Write_UINT16(in_s, in_count);
324 #define OUT_FILL_COUNT3(in_count, in_s) in_count = out_fill_count_3(in_count, in_s)
328 static INLINE UINT16 out_mix_count_2(UINT16 in_count,
wStream* WINPR_RESTRICT in_s)
334 const BYTE temp = ((0x1 << 5) | in_count) & 0xFF;
335 Stream_Write_UINT8(in_s, temp);
337 else if (in_count < 256 + 32)
339 const BYTE temp = (in_count - 32) & 0xFF;
340 Stream_Write_UINT8(in_s, 0x20);
341 Stream_Write_UINT8(in_s, temp);
345 Stream_Write_UINT8(in_s, 0xf1);
346 Stream_Write_UINT16(in_s, in_count);
352 #define OUT_MIX_COUNT2(in_count, in_s) in_count = out_mix_count_2(in_count, in_s)
356 static INLINE UINT16 out_mix_count_3(UINT16 in_count,
wStream* WINPR_RESTRICT in_s)
362 const BYTE temp = ((0x1 << 5) | in_count) & 0xFF;
363 Stream_Write_UINT8(in_s, temp);
365 else if (in_count < 256 + 32)
367 const BYTE temp = (in_count - 32) & 0xFF;
368 Stream_Write_UINT8(in_s, 0x20);
369 Stream_Write_UINT8(in_s, temp);
373 Stream_Write_UINT8(in_s, 0xf1);
374 Stream_Write_UINT16(in_s, in_count);
381 #define OUT_MIX_COUNT3(in_count, in_s) in_count = out_mix_count_3(in_count, in_s)
385 static INLINE UINT16 out_from_count_2(UINT16 in_count,
wStream* WINPR_RESTRICT in_s,
386 const int8_t* WINPR_RESTRICT in_mask,
size_t in_mask_len)
390 if ((in_count % 8) == 0 && in_count < 249)
392 const BYTE temp = ((0x2 << 5) | (in_count / 8)) & 0xFF;
393 Stream_Write_UINT8(in_s, temp);
395 else if (in_count < 256)
397 const BYTE temp = (in_count - 1) & 0xFF;
398 Stream_Write_UINT8(in_s, 0x40);
399 Stream_Write_UINT8(in_s, temp);
403 Stream_Write_UINT8(in_s, 0xf2);
404 Stream_Write_UINT16(in_s, in_count);
407 Stream_Write(in_s, in_mask, in_mask_len);
412 #define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \
413 in_count = out_from_count_2(in_count, in_s, in_mask, in_mask_len)
417 static INLINE UINT16 out_from_count_3(UINT16 in_count,
wStream* WINPR_RESTRICT in_s,
418 const int8_t* WINPR_RESTRICT in_mask,
size_t in_mask_len)
422 if ((in_count % 8) == 0 && in_count < 249)
424 const BYTE temp = ((0x2 << 5) | (in_count / 8)) & 0xFF;
425 Stream_Write_UINT8(in_s, temp);
427 else if (in_count < 256)
429 const BYTE temp = (in_count - 1) & 0xFF;
430 Stream_Write_UINT8(in_s, 0x40);
431 Stream_Write_UINT8(in_s, temp);
435 Stream_Write_UINT8(in_s, 0xf2);
436 Stream_Write_UINT16(in_s, in_count);
439 Stream_Write(in_s, in_mask, in_mask_len);
444 #define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \
445 in_count = out_from_count_3(in_count, in_s, in_mask, in_mask_len)
447 #define TEST_FILL ((last_line == 0 && pixel == 0) || (last_line != 0 && pixel == ypixel))
448 #define TEST_MIX ((last_line == 0 && pixel == mix) || (last_line != 0 && pixel == (ypixel ^ mix)))
449 #define TEST_FOM TEST_FILL || TEST_MIX
450 #define TEST_COLOR pixel == last_pixel
451 #define TEST_BICOLOR \
452 ((pixel != last_pixel) && \
453 ((!bicolor_spin && (pixel == bicolor1) && (last_pixel == bicolor2)) || \
454 (bicolor_spin && (pixel == bicolor2) && (last_pixel == bicolor1))))
455 #define RESET_COUNTS \
464 bicolor_spin = FALSE; \
467 static INLINE SSIZE_T freerdp_bitmap_compress_24(
const void* WINPR_RESTRICT srcData, UINT32 width,
468 UINT32 height,
wStream* WINPR_RESTRICT s,
469 UINT32 byte_limit, UINT32 start_line,
470 wStream* WINPR_RESTRICT temp_s, UINT32 e)
472 int8_t fom_mask[8192] = { 0 };
473 SSIZE_T lines_sent = 0;
475 UINT16 color_count = 0;
476 UINT32 last_pixel = 0;
477 UINT32 last_ypixel = 0;
478 UINT16 bicolor_count = 0;
481 BOOL bicolor_spin = FALSE;
482 UINT32 end = width + e;
483 UINT32 out_count = end * 3;
484 UINT16 fill_count = 0;
485 UINT16 mix_count = 0;
486 const UINT32 mix = 0xFFFFFF;
487 UINT16 fom_count = 0;
488 size_t fom_mask_len = 0;
489 const char* start = (
const char*)srcData;
490 const char* line = start + 4ULL * width * start_line;
491 const char* last_line = NULL;
493 while ((line >= start) && (out_count < 32768))
495 size_t i = Stream_GetPosition(s) + 3ULL * count;
497 if ((i - (3ULL * color_count) >= byte_limit) &&
498 (i - (3ULL * bicolor_count) >= byte_limit) && (i - (3ULL * fill_count) >= byte_limit) &&
499 (i - (3ULL * mix_count) >= byte_limit) && (i - (3ULL * fom_count) >= byte_limit))
504 out_count += end * 3;
506 for (UINT32 j = 0; j < end; j++)
509 const UINT32 pixel = IN_PIXEL32(line, j, 0, width, last_pixel);
510 const UINT32 ypixel = IN_PIXEL32(last_line, j, 0, width, last_ypixel);
514 if (fill_count > 3 && fill_count >= color_count && fill_count >= bicolor_count &&
515 fill_count >= mix_count && fill_count >= fom_count)
517 if (fill_count > count)
521 OUT_COPY_COUNT3(count, s, temp_s);
522 OUT_FILL_COUNT3(fill_count, s);
531 if (mix_count > 3 && mix_count >= fill_count && mix_count >= bicolor_count &&
532 mix_count >= color_count && mix_count >= fom_count)
534 if (mix_count > count)
538 OUT_COPY_COUNT3(count, s, temp_s);
539 OUT_MIX_COUNT3(mix_count, s);
548 if (color_count > 3 && color_count >= fill_count && color_count >= bicolor_count &&
549 color_count >= mix_count && color_count >= fom_count)
551 if (color_count > count)
554 count -= color_count;
555 OUT_COPY_COUNT3(count, s, temp_s);
556 OUT_COLOR_COUNT3(color_count, s, last_pixel);
565 if (bicolor_count > 3 && bicolor_count >= fill_count &&
566 bicolor_count >= color_count && bicolor_count >= mix_count &&
567 bicolor_count >= fom_count)
569 if ((bicolor_count % 2) != 0)
572 if (bicolor_count > count)
575 count -= bicolor_count;
576 OUT_COPY_COUNT3(count, s, temp_s);
577 OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1);
582 bicolor1 = last_pixel;
584 bicolor_spin = FALSE;
589 if (fom_count > 3 && fom_count >= fill_count && fom_count >= color_count &&
590 fom_count >= mix_count && fom_count >= bicolor_count)
592 if (fom_count > count)
596 OUT_COPY_COUNT3(count, s, temp_s);
597 OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len);
622 bicolor_spin = !bicolor_spin;
628 if ((fom_count % 8) == 0)
630 fom_mask[fom_mask_len] = 0;
634 if (pixel == (ypixel ^ mix))
636 fom_mask[fom_mask_len - 1] |=
637 WINPR_ASSERTING_INT_CAST(int8_t, (1 << (fom_count % 8)));
643 Stream_Write_UINT8(temp_s, pixel & 0xff);
644 Stream_Write_UINT8(temp_s, (pixel >> 8) & 0xff);
645 Stream_Write_UINT8(temp_s, (pixel >> 16) & 0xff);
648 last_ypixel = ypixel;
654 if (fill_count > 3 && fill_count >= color_count && fill_count >= bicolor_count &&
655 fill_count >= mix_count && fill_count >= fom_count)
657 if (fill_count > count)
661 OUT_COPY_COUNT3(count, s, temp_s);
662 OUT_FILL_COUNT3(fill_count, s);
668 if (mix_count > 3 && mix_count >= fill_count && mix_count >= bicolor_count &&
669 mix_count >= color_count && mix_count >= fom_count)
671 if (mix_count > count)
675 OUT_COPY_COUNT3(count, s, temp_s);
676 OUT_MIX_COUNT3(mix_count, s);
682 if (fom_count > 3 && fom_count >= fill_count && fom_count >= color_count &&
683 fom_count >= mix_count && fom_count >= bicolor_count)
685 if (fom_count > count)
689 OUT_COPY_COUNT3(count, s, temp_s);
690 OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len);
699 line = line - 4ULL * width;
704 Stream_SetPosition(temp_s, 0);
706 if (fill_count > 3 && fill_count >= color_count && fill_count >= bicolor_count &&
707 fill_count >= mix_count && fill_count >= fom_count)
709 if (fill_count > count)
713 OUT_COPY_COUNT3(count, s, temp_s);
714 OUT_FILL_COUNT3(fill_count, s);
716 else if (mix_count > 3 && mix_count >= color_count && mix_count >= bicolor_count &&
717 mix_count >= fill_count && mix_count >= fom_count)
719 if (mix_count > count)
723 OUT_COPY_COUNT3(count, s, temp_s);
724 OUT_MIX_COUNT3(mix_count, s);
726 else if (color_count > 3 && color_count >= mix_count && color_count >= bicolor_count &&
727 color_count >= fill_count && color_count >= fom_count)
729 if (color_count > count)
732 count -= color_count;
733 OUT_COPY_COUNT3(count, s, temp_s);
734 OUT_COLOR_COUNT3(color_count, s, last_pixel);
736 else if (bicolor_count > 3 && bicolor_count >= mix_count && bicolor_count >= color_count &&
737 bicolor_count >= fill_count && bicolor_count >= fom_count)
739 if ((bicolor_count % 2) != 0)
742 if (bicolor_count > count)
745 count -= bicolor_count;
746 OUT_COPY_COUNT3(count, s, temp_s);
747 OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1);
749 if (bicolor_count > count)
752 count -= bicolor_count;
753 OUT_COPY_COUNT3(count, s, temp_s);
754 OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2);
756 else if (fom_count > 3 && fom_count >= mix_count && fom_count >= color_count &&
757 fom_count >= fill_count && fom_count >= bicolor_count)
759 if (fom_count > count)
763 OUT_COPY_COUNT3(count, s, temp_s);
764 OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len);
768 OUT_COPY_COUNT3(count, s, temp_s);
774 static INLINE SSIZE_T freerdp_bitmap_compress_16(
const void* WINPR_RESTRICT srcData, UINT32 width,
775 UINT32 height,
wStream* WINPR_RESTRICT s,
776 UINT32 bpp, UINT32 byte_limit, UINT32 start_line,
777 wStream* WINPR_RESTRICT temp_s, UINT32 e)
779 int8_t fom_mask[8192] = { 0 };
780 SSIZE_T lines_sent = 0;
782 UINT16 color_count = 0;
783 UINT16 last_pixel = 0;
784 UINT16 last_ypixel = 0;
785 UINT16 bicolor_count = 0;
788 BOOL bicolor_spin = FALSE;
789 UINT32 end = width + e;
790 UINT32 out_count = end * 2;
791 UINT16 fill_count = 0;
792 UINT16 mix_count = 0;
793 const UINT32 mix = (bpp == 15) ? 0xBA1F : 0xFFFF;
794 UINT16 fom_count = 0;
795 size_t fom_mask_len = 0;
796 const char* start = (
const char*)srcData;
797 const char* line = start + 2ULL * width * start_line;
798 const char* last_line = NULL;
800 while ((line >= start) && (out_count < 32768))
802 size_t i = Stream_GetPosition(s) + 2ULL * count;
804 if ((i - (2ULL * color_count) >= byte_limit) &&
805 (i - (2ULL * bicolor_count) >= byte_limit) && (i - (2ULL * fill_count) >= byte_limit) &&
806 (i - (2ULL * mix_count) >= byte_limit) && (i - (2ULL * fom_count) >= byte_limit))
811 out_count += end * 2;
813 for (UINT32 j = 0; j < end; j++)
816 const UINT16 pixel = IN_PIXEL16(line, j, 0, width, last_pixel);
817 const UINT16 ypixel = IN_PIXEL16(last_line, j, 0, width, last_ypixel);
821 if (fill_count > 3 && fill_count >= color_count && fill_count >= bicolor_count &&
822 fill_count >= mix_count && fill_count >= fom_count)
824 if (fill_count > count)
828 OUT_COPY_COUNT2(count, s, temp_s);
829 OUT_FILL_COUNT2(fill_count, s);
838 if (mix_count > 3 && mix_count >= fill_count && mix_count >= bicolor_count &&
839 mix_count >= color_count && mix_count >= fom_count)
841 if (mix_count > count)
845 OUT_COPY_COUNT2(count, s, temp_s);
846 OUT_MIX_COUNT2(mix_count, s);
855 if (color_count > 3 && color_count >= fill_count && color_count >= bicolor_count &&
856 color_count >= mix_count && color_count >= fom_count)
858 if (color_count > count)
861 count -= color_count;
862 OUT_COPY_COUNT2(count, s, temp_s);
863 OUT_COLOR_COUNT2(color_count, s, last_pixel);
872 if ((bicolor_count > 3) && (bicolor_count >= fill_count) &&
873 (bicolor_count >= color_count) && (bicolor_count >= mix_count) &&
874 (bicolor_count >= fom_count))
876 if ((bicolor_count % 2) != 0)
879 if (bicolor_count > count)
882 count -= bicolor_count;
883 OUT_COPY_COUNT2(count, s, temp_s);
884 OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1);
889 bicolor1 = last_pixel;
891 bicolor_spin = FALSE;
896 if (fom_count > 3 && fom_count >= fill_count && fom_count >= color_count &&
897 fom_count >= mix_count && fom_count >= bicolor_count)
899 if (fom_count > count)
903 OUT_COPY_COUNT2(count, s, temp_s);
904 OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len);
929 bicolor_spin = !bicolor_spin;
935 if ((fom_count % 8) == 0)
937 fom_mask[fom_mask_len] = 0;
941 if (pixel == (ypixel ^ mix))
943 fom_mask[fom_mask_len - 1] |=
944 WINPR_ASSERTING_INT_CAST(int8_t, (1 << (fom_count % 8)));
950 Stream_Write_UINT16(temp_s, pixel);
953 last_ypixel = ypixel;
959 if (fill_count > 3 && fill_count >= color_count && fill_count >= bicolor_count &&
960 fill_count >= mix_count && fill_count >= fom_count)
962 if (fill_count > count)
966 OUT_COPY_COUNT2(count, s, temp_s);
967 OUT_FILL_COUNT2(fill_count, s);
973 if (mix_count > 3 && mix_count >= fill_count && mix_count >= bicolor_count &&
974 mix_count >= color_count && mix_count >= fom_count)
976 if (mix_count > count)
980 OUT_COPY_COUNT2(count, s, temp_s);
981 OUT_MIX_COUNT2(mix_count, s);
987 if (fom_count > 3 && fom_count >= fill_count && fom_count >= color_count &&
988 fom_count >= mix_count && fom_count >= bicolor_count)
990 if (fom_count > count)
994 OUT_COPY_COUNT2(count, s, temp_s);
995 OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len);
1004 line = line - 2ULL * width;
1009 Stream_SetPosition(temp_s, 0);
1011 if (fill_count > 3 && fill_count >= color_count && fill_count >= bicolor_count &&
1012 fill_count >= mix_count && fill_count >= fom_count)
1014 if (fill_count > count)
1017 count -= fill_count;
1018 OUT_COPY_COUNT2(count, s, temp_s);
1019 OUT_FILL_COUNT2(fill_count, s);
1021 else if (mix_count > 3 && mix_count >= color_count && mix_count >= bicolor_count &&
1022 mix_count >= fill_count && mix_count >= fom_count)
1024 if (mix_count > count)
1028 OUT_COPY_COUNT2(count, s, temp_s);
1029 OUT_MIX_COUNT2(mix_count, s);
1031 else if (color_count > 3 && color_count >= mix_count && color_count >= bicolor_count &&
1032 color_count >= fill_count && color_count >= fom_count)
1034 if (color_count > count)
1037 count -= color_count;
1038 OUT_COPY_COUNT2(count, s, temp_s);
1039 OUT_COLOR_COUNT2(color_count, s, last_pixel);
1041 else if (bicolor_count > 3 && bicolor_count >= mix_count && bicolor_count >= color_count &&
1042 bicolor_count >= fill_count && bicolor_count >= fom_count)
1044 if ((bicolor_count % 2) != 0)
1047 if (bicolor_count > count)
1050 count -= bicolor_count;
1051 OUT_COPY_COUNT2(count, s, temp_s);
1052 OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1);
1054 if (bicolor_count > count)
1057 count -= bicolor_count;
1058 OUT_COPY_COUNT2(count, s, temp_s);
1059 OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2);
1061 else if (fom_count > 3 && fom_count >= mix_count && fom_count >= color_count &&
1062 fom_count >= fill_count && fom_count >= bicolor_count)
1064 if (fom_count > count)
1068 OUT_COPY_COUNT2(count, s, temp_s);
1069 OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len);
1073 OUT_COPY_COUNT2(count, s, temp_s);
1079 SSIZE_T freerdp_bitmap_compress(
const void* WINPR_RESTRICT srcData, UINT32 width, UINT32 height,
1080 wStream* WINPR_RESTRICT s, UINT32 bpp, UINT32 byte_limit,
1081 UINT32 start_line,
wStream* WINPR_RESTRICT temp_s, UINT32 e)
1083 Stream_SetPosition(temp_s, 0);
1089 return freerdp_bitmap_compress_16(srcData, width, height, s, bpp, byte_limit,
1090 start_line, temp_s, e);
1093 return freerdp_bitmap_compress_24(srcData, width, height, s, byte_limit, start_line,