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