1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** GUIX Component */
17 /** */
18 /** Image Reader Management(Image Reader) */
19 /** */
20 /**************************************************************************/
21
22 #define GX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "gx_api.h"
28 #include "gx_image_reader.h"
29 #include "gx_system.h"
30
31 #if defined(GX_SOFTWARE_DECODER_SUPPORT)
32
33 #define PIXEL_CMP(_p1, _p2) \
34 (_p1.gx_pixel_alpha == _p2.gx_pixel_alpha) && \
35 (_p1.gx_pixel_red == _p2.gx_pixel_red) && \
36 (_p1.gx_pixel_green == _p2.gx_pixel_green) && \
37 (_p1.gx_pixel_blue == _p2.gx_pixel_blue)
38
39 /**************************************************************************/
40 /* */
41 /* FUNCTION RELEASE */
42 /* */
43 /* _gx_image_reader_rle_count_location_get PORTABLE C */
44 /* 6.1 */
45 /* AUTHOR */
46 /* */
47 /* Kenneth Maxwell, Microsoft Corporation */
48 /* */
49 /* DESCRIPTION */
50 /* */
51 /* This function retrieves the count put position. */
52 /* */
53 /* INPUT */
54 /* */
55 /* image_reader Image reader control block. */
56 /* put_count Retrieved count put position. */
57 /* */
58 /* OUTPUT */
59 /* */
60 /* status Completion status */
61 /* */
62 /* CALLS */
63 /* */
64 /* None */
65 /* */
66 /* CALLED BY */
67 /* */
68 /* _gx_image_reader_rle_one_row_encode */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
75 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
76 /* resulting in version 6.1 */
77 /* */
78 /**************************************************************************/
_gx_image_reader_rle_count_location_get(GX_IMAGE_READER * image_reader,GX_UBYTE ** put_count)79 static UINT _gx_image_reader_rle_count_location_get(GX_IMAGE_READER *image_reader, GX_UBYTE **put_count)
80 {
81 switch (image_reader -> gx_image_reader_color_format)
82 {
83 case GX_COLOR_FORMAT_32ARGB:
84 case GX_COLOR_FORMAT_24XRGB:
85 (*put_count) = image_reader -> gx_image_reader_putauxdata++;
86 break;
87
88 case GX_COLOR_FORMAT_565RGB:
89 case GX_COLOR_FORMAT_1555XRGB:
90 if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
91 {
92 (*put_count) = image_reader -> gx_image_reader_putdata;
93 }
94 else
95 {
96 (*put_count) = image_reader -> gx_image_reader_putdata;
97 image_reader -> gx_image_reader_putdata += 2;
98 }
99 break;
100
101 case GX_COLOR_FORMAT_4444ARGB:
102 (*put_count) = image_reader -> gx_image_reader_putdata;
103 image_reader -> gx_image_reader_putdata += 2;
104 break;
105
106 case GX_COLOR_FORMAT_8BIT_GRAY:
107 case GX_COLOR_FORMAT_8BIT_ALPHAMAP:
108 case GX_COLOR_FORMAT_8BIT_PALETTE:
109 (*put_count) = image_reader -> gx_image_reader_putdata++;
110 break;
111
112 case GX_COLOR_FORMAT_4BIT_GRAY:
113 (*put_count) = image_reader -> gx_image_reader_putauxdata++;
114 break;
115
116 case GX_COLOR_FORMAT_MONOCHROME:
117 (*put_count) = image_reader -> gx_image_reader_putdata;
118 break;
119
120 default:
121 return GX_NOT_SUPPORTED;
122 }
123
124 return GX_SUCCESS;
125 }
126
127
128 /**************************************************************************/
129 /* */
130 /* FUNCTION RELEASE */
131 /* */
132 /* _gx_image_reader_rle_count_write PORTABLE C */
133 /* 6.1 */
134 /* AUTHOR */
135 /* */
136 /* Kenneth Maxwell, Microsoft Corporation */
137 /* */
138 /* DESCRIPTION */
139 /* */
140 /* This function writes repeat count to output pixelmap data structure.*/
141 /* */
142 /* INPUT */
143 /* */
144 /* image_reader Image reader control block. */
145 /* count The number of pixels that */
146 /* follows. */
147 /* put_count The position to put "count". */
148 /* repeat Wheather the following pixels */
149 /* are repeated or not. */
150 /* */
151 /* OUTPUT */
152 /* */
153 /* status Completion status */
154 /* */
155 /* CALLS */
156 /* */
157 /* None */
158 /* */
159 /* CALLED BY */
160 /* */
161 /* _gx_image_reader_rle_one_row_encode */
162 /* */
163 /* RELEASE HISTORY */
164 /* */
165 /* DATE NAME DESCRIPTION */
166 /* */
167 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
168 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
169 /* resulting in version 6.1 */
170 /* */
171 /**************************************************************************/
_gx_image_reader_rle_count_write(GX_IMAGE_READER * image_reader,INT * count,GX_UBYTE * put_count,GX_BOOL repeat)172 static UINT _gx_image_reader_rle_count_write(GX_IMAGE_READER *image_reader, INT *count,
173 GX_UBYTE *put_count, GX_BOOL repeat)
174 {
175 INT write_count;
176
177 write_count = (*count) - 1;
178
179 switch (image_reader -> gx_image_reader_color_format)
180 {
181 case GX_COLOR_FORMAT_565RGB:
182 case GX_COLOR_FORMAT_1555XRGB:
183 if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
184 {
185 if (write_count > 127)
186 {
187 write_count = 127;
188 }
189
190 if (repeat)
191 {
192 write_count |= 0x80;
193 }
194
195 if (!image_reader -> gx_image_reader_size_testing)
196 {
197 *put_count = (GX_UBYTE)write_count;
198 }
199
200 (*count) = (write_count & 0x7f) + 1;
201 }
202 else
203 {
204 if (repeat)
205 {
206 write_count |= 0x8000;
207 }
208
209 if (!image_reader -> gx_image_reader_size_testing)
210 {
211 *((USHORT *)put_count) = (USHORT)write_count;
212 }
213
214 (*count) = (write_count & 0x7fff) + 1;
215 }
216 break;
217
218 case GX_COLOR_FORMAT_4444ARGB:
219 if (repeat)
220 {
221 write_count |= 0x8000;
222 }
223
224 if (!image_reader -> gx_image_reader_size_testing)
225 {
226 *((USHORT *)put_count) = (USHORT)write_count;
227 }
228
229 *count = (write_count & 0x7fff) + 1;
230 break;
231
232 case GX_COLOR_FORMAT_MONOCHROME:
233 if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
234 {
235 if (write_count > 0x1f)
236 {
237 write_count = 0x1f;
238 }
239 if (repeat)
240 {
241 write_count |= 0x20;
242 }
243 if (!image_reader -> gx_image_reader_size_testing)
244 {
245 *put_count |= (GX_UBYTE)(write_count << 2);
246 }
247
248 (*count) = (write_count & 0x1f) + 1;
249 }
250 else
251 {
252 if (write_count > 0x3f)
253 {
254 write_count = 0x3f;
255 }
256 if (repeat)
257 {
258 write_count |= 0x40;
259 }
260 if (!image_reader -> gx_image_reader_size_testing)
261 {
262 (*put_count) |= (GX_UBYTE)(write_count << 1);
263 }
264
265 (*count) = (write_count & 0x3f) + 1;
266 }
267 break;
268
269 case GX_COLOR_FORMAT_4BIT_GRAY:
270 default:
271 if (write_count > 127)
272 {
273 write_count = 127;
274 }
275
276 if (repeat)
277 {
278 write_count |= 0x80;
279 }
280
281 if (!image_reader -> gx_image_reader_size_testing)
282 {
283 (*put_count) = (GX_UBYTE)write_count;
284 }
285
286 (*count) = (write_count & 0x7f) + 1;
287 break;
288 }
289
290 return GX_SUCCESS;
291 }
292
293 /**************************************************************************/
294 /* */
295 /* FUNCTION RELEASE */
296 /* */
297 /* _gx_image_reader_rle_duplicates_count PORTABLE C */
298 /* 6.1 */
299 /* AUTHOR */
300 /* */
301 /* Kenneth Maxwell, Microsoft Corporation */
302 /* */
303 /* DESCRIPTION */
304 /* */
305 /* This function calculates the number of duplicate pixels. */
306 /* */
307 /* INPUT */
308 /* */
309 /* image_reader Image reader control block. */
310 /* index Position of the pixel to */
311 /* calcualte from. */
312 /* repeat_counts The number of duplicate pixels.*/
313 /* */
314 /* OUTPUT */
315 /* */
316 /* Completion status */
317 /* */
318 /* CALLS */
319 /* */
320 /* None */
321 /* */
322 /* CALLED BY */
323 /* */
324 /* _gx_image_reader_rle_one_row_encode */
325 /* */
326 /* RELEASE HISTORY */
327 /* */
328 /* DATE NAME DESCRIPTION */
329 /* */
330 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
331 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
332 /* resulting in version 6.1 */
333 /* */
334 /**************************************************************************/
_gx_image_reader_rle_duplicates_count(GX_IMAGE_READER * image_reader,INT index,INT * repeat_counts)335 static UINT _gx_image_reader_rle_duplicates_count(GX_IMAGE_READER *image_reader, INT index, INT *repeat_counts)
336 {
337 UINT width;
338 INT duplicates = 1;
339 GX_PIXEL pre_pixel;
340 GX_PIXEL cur_pixel;
341
342
343 image_reader -> gx_image_reader_pixel_read(image_reader, index++, &pre_pixel);
344
345 width = image_reader -> gx_image_reader_image_width;
346
347 while ((UINT)index < width)
348 {
349 image_reader -> gx_image_reader_pixel_read(image_reader, index, &cur_pixel);
350
351 if (PIXEL_CMP(pre_pixel, cur_pixel))
352 {
353 duplicates++;
354 }
355 else
356 {
357 break;
358 }
359 index++;
360 }
361
362 (*repeat_counts) = duplicates;
363
364 return GX_SUCCESS;
365 }
366
367 /**************************************************************************/
368 /* */
369 /* FUNCTION RELEASE */
370 /* */
371 /* _gx_image_reader_rle_one_row_encode PORTABLE C */
372 /* 6.1 */
373 /* AUTHOR */
374 /* */
375 /* Kenneth Maxwell, Microsoft Corporation */
376 /* */
377 /* DESCRIPTION */
378 /* */
379 /* This funcitons encodes one row of the input pixelmap. */
380 /* */
381 /* INPUT */
382 /* */
383 /* image_reader Image reader control block. */
384 /* */
385 /* OUTPUT */
386 /* */
387 /* status Completion status */
388 /* */
389 /* CALLS */
390 /* */
391 /* _gx_image_reader_rle_duplicates_count Calculate the number of */
392 /* duplicate pixels */
393 /* _gx_image_reader_rle_count_write Write out duplicated pixel */
394 /* count */
395 /* _gx_image_reader_rle_count_location_get */
396 /* Retrieve the address to put */
397 /* duplicated pixel count */
398 /* */
399 /* */
400 /* CALLED BY */
401 /* */
402 /* _gx_image_reader_rle_encode */
403 /* */
404 /* RELEASE HISTORY */
405 /* */
406 /* DATE NAME DESCRIPTION */
407 /* */
408 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
409 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
410 /* resulting in version 6.1 */
411 /* */
412 /**************************************************************************/
_gx_image_reader_rle_one_row_encode(GX_IMAGE_READER * image_reader)413 static UINT _gx_image_reader_rle_one_row_encode(GX_IMAGE_READER *image_reader)
414 {
415 UINT status = GX_SUCCESS;
416 UINT col = 0;
417 INT raw_count = 0;
418 INT count = 0;
419 GX_UBYTE *putCount = GX_NULL;
420 UINT width;
421 GX_PIXEL pixel;
422
423 width = image_reader -> gx_image_reader_image_width;
424
425 while (col < width)
426 {
427 /* Calculate the number of duplicate pixels. */
428 _gx_image_reader_rle_duplicates_count(image_reader, (INT)col, &count);
429
430 if (count >= 3)
431 {
432 if (raw_count)
433 {
434 _gx_image_reader_rle_count_write(image_reader, &raw_count, putCount, GX_FALSE);
435 }
436
437 /* Retrieve the count put position. */
438 status = _gx_image_reader_rle_count_location_get(image_reader, &putCount);
439
440 if (status != GX_SUCCESS)
441 {
442 return status;
443 }
444
445 /* Write count. */
446 _gx_image_reader_rle_count_write(image_reader, &count, putCount, GX_TRUE);
447
448 image_reader -> gx_image_reader_pixel_read(image_reader, (INT)col, &pixel);
449
450 /* Write pixel value. */
451 image_reader -> gx_image_reader_pixel_write(image_reader, &pixel);
452
453 col += (UINT)count;
454 raw_count = 0;
455 }
456 else
457 {
458
459 if (!raw_count)
460 {
461 status = _gx_image_reader_rle_count_location_get(image_reader, &putCount);
462
463 if (status != GX_SUCCESS)
464 {
465 return status;
466 }
467 }
468
469 raw_count++;
470
471 image_reader -> gx_image_reader_pixel_read(image_reader, (INT)col, &pixel);
472
473 /* Write pixel value. */
474 image_reader -> gx_image_reader_pixel_write(image_reader, &pixel);
475
476 col++;
477
478 if (raw_count == 128 || col == width)
479 {
480 _gx_image_reader_rle_count_write(image_reader, &raw_count, putCount, GX_FALSE);
481
482 raw_count = 0;
483 }
484 }
485 }
486
487 return status;
488 }
489
490 /**************************************************************************/
491 /* */
492 /* FUNCTION RELEASE */
493 /* */
494 /* _gx_image_reader_rle_encode_size_get PORTABLE C */
495 /* 6.1 */
496 /* AUTHOR */
497 /* */
498 /* Kenneth Maxwell, Microsoft Corporation */
499 /* */
500 /* DESCRIPTION */
501 /* */
502 /* This function gets the size of encoded pixelmap. */
503 /* */
504 /* INPUT */
505 /* */
506 /* image_reader Image reader control block. */
507 /* datasize Retrieved data size. */
508 /* auxsize Retrieved aux data size. */
509 /* */
510 /* OUTPUT */
511 /* */
512 /* Completion status */
513 /* */
514 /* CALLS */
515 /* */
516 /* _gx_image_reader_rle_one_row_encode Process one row encoding */
517 /* */
518 /* CALLED BY */
519 /* */
520 /* _gx_image_reader_rle_colorspace_convert */
521 /* */
522 /* RELEASE HISTORY */
523 /* */
524 /* DATE NAME DESCRIPTION */
525 /* */
526 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
527 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
528 /* resulting in version 6.1 */
529 /* */
530 /**************************************************************************/
_gx_image_reader_rle_encode_size_get(GX_IMAGE_READER * image_reader,UINT * data_size,UINT * aux_size)531 UINT _gx_image_reader_rle_encode_size_get(GX_IMAGE_READER *image_reader, UINT *data_size, UINT *aux_size)
532 {
533 UINT status = GX_SUCCESS;
534 UINT row;
535 UINT height;
536 UINT width;
537 UINT aux_stride;
538
539
540 height = image_reader -> gx_image_reader_image_height;
541 width = image_reader -> gx_image_reader_image_width;
542 aux_stride = width;
543
544 /* Process rle encode logic, but not output compressed data. */
545 image_reader -> gx_image_reader_size_testing = GX_TRUE;
546 image_reader -> gx_image_reader_putdata = GX_NULL;
547 image_reader -> gx_image_reader_putauxdata = GX_NULL;
548
549 switch (image_reader -> gx_image_reader_color_format)
550 {
551 case GX_COLOR_FORMAT_4BIT_GRAY:
552 if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
553 {
554 aux_stride = (aux_stride + 7) >> 3;
555 }
556 break;
557 }
558
559 /* Test size of compressed data to see if it is smaller. */
560 for (row = 0; row < height; row++)
561 {
562 status = _gx_image_reader_rle_one_row_encode(image_reader);
563
564 if (status != GX_SUCCESS)
565 {
566 return status;
567 }
568
569 image_reader -> gx_image_reader_getdata += image_reader -> gx_image_reader_input_stride;
570 image_reader -> gx_image_reader_getauxdata += aux_stride;
571 }
572
573 if (image_reader -> gx_image_reader_color_format == GX_COLOR_FORMAT_4BIT_GRAY)
574 {
575 if (!(image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA) &&
576 image_reader -> gx_image_reader_putdata_mask == 0x0f)
577 {
578 image_reader -> gx_image_reader_putdata++;
579 }
580 }
581
582 (*data_size) = (UINT)image_reader -> gx_image_reader_putdata;
583 (*aux_size) = (UINT)image_reader -> gx_image_reader_putauxdata;
584
585 return status;
586 }
587
588 /**************************************************************************/
589 /* */
590 /* FUNCTION RELEASE */
591 /* */
592 /* _gx_image_reader_rle_encode PORTABLE C */
593 /* 6.1 */
594 /* AUTHOR */
595 /* */
596 /* Kenneth Maxwell, Microsoft Corporation */
597 /* */
598 /* DESCRIPTION */
599 /* */
600 /* This function converts a raw map into a compressed map. */
601 /* */
602 /* INPUT */
603 /* */
604 /* image_reader Image reader control block. */
605 /* outmap Encoded pixelmap. */
606 /* */
607 /* OUTPUT */
608 /* */
609 /* Completion status */
610 /* */
611 /* CALLS */
612 /* */
613 /* _gx_image_reader_rle_one_row_encode Process one row encoding */
614 /* */
615 /* CALLED BY */
616 /* */
617 /* _gx_image_reader_rle_colorspace_convert */
618 /* */
619 /* RELEASE HISTORY */
620 /* */
621 /* DATE NAME DESCRIPTION */
622 /* */
623 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
624 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
625 /* resulting in version 6.1 */
626 /* */
627 /**************************************************************************/
_gx_image_reader_rle_encode(GX_IMAGE_READER * image_reader,GX_PIXELMAP * outmap)628 UINT _gx_image_reader_rle_encode(GX_IMAGE_READER *image_reader, GX_PIXELMAP *outmap)
629 {
630 UINT status = GX_SUCCESS;
631 GX_VALUE height;
632 GX_VALUE width;
633 INT row;
634 GX_VALUE aux_stride;
635
636 height = outmap -> gx_pixelmap_height;
637 width = outmap -> gx_pixelmap_width;
638 aux_stride = width;
639
640 /* If size testing is TRUE, process rle encode logic but not output compressed data.
641 If size testing is FALSE, process rle encode logic, and output compressed data. */
642 image_reader -> gx_image_reader_size_testing = GX_FALSE;
643
644 switch (image_reader -> gx_image_reader_color_format)
645 {
646 case GX_COLOR_FORMAT_4BIT_GRAY:
647 if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
648 {
649 aux_stride = (GX_VALUE)((aux_stride + 7) >> 3);
650 }
651 break;
652 }
653
654 /* Process RLE encode. */
655 for (row = 0; row < height; row++)
656 {
657 /* Encode one row data. */
658 status = _gx_image_reader_rle_one_row_encode(image_reader);
659
660 if (status != GX_SUCCESS)
661 {
662 return status;
663 }
664
665 image_reader -> gx_image_reader_getdata += image_reader -> gx_image_reader_input_stride;
666 image_reader -> gx_image_reader_getauxdata += aux_stride;
667 }
668
669 return status;
670 }
671 #endif
672
673