OLD | NEW |
1 /* | 1 /* |
2 * jdcolor.c | 2 * jdcolor.c |
3 * | 3 * |
4 * This file was part of the Independent JPEG Group's software: | 4 * This file was part of the Independent JPEG Group's software: |
5 * Copyright (C) 1991-1997, Thomas G. Lane. | 5 * Copyright (C) 1991-1997, Thomas G. Lane. |
6 * Modified 2011 by Guido Vollbeding. | 6 * Modified 2011 by Guido Vollbeding. |
7 * libjpeg-turbo Modifications: | 7 * libjpeg-turbo Modifications: |
8 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB | 8 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB |
9 * Copyright (C) 2009, 2011-2012, D. R. Commander. | 9 * Copyright (C) 2009, 2011-2012, 2014, D. R. Commander. |
| 10 * Copyright (C) 2013, Linaro Limited. |
10 * For conditions of distribution and use, see the accompanying README file. | 11 * For conditions of distribution and use, see the accompanying README file. |
11 * | 12 * |
12 * This file contains output colorspace conversion routines. | 13 * This file contains output colorspace conversion routines. |
13 */ | 14 */ |
14 | 15 |
15 #define JPEG_INTERNALS | 16 #define JPEG_INTERNALS |
16 #include "jinclude.h" | 17 #include "jinclude.h" |
17 #include "jpeglib.h" | 18 #include "jpeglib.h" |
18 #include "jsimd.h" | 19 #include "jsimd.h" |
19 #include "config.h" | 20 #include "config.h" |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ | 538 outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ |
538 /* K passes through unchanged */ | 539 /* K passes through unchanged */ |
539 outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ | 540 outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ |
540 outptr += 4; | 541 outptr += 4; |
541 } | 542 } |
542 } | 543 } |
543 } | 544 } |
544 | 545 |
545 | 546 |
546 /* | 547 /* |
| 548 * RGB565 conversion |
| 549 */ |
| 550 |
| 551 #define PACK_SHORT_565_LE(r, g, b) ((((r) << 8) & 0xF800) | \ |
| 552 (((g) << 3) & 0x7E0) | ((b) >> 3)) |
| 553 #define PACK_SHORT_565_BE(r, g, b) (((r) & 0xF8) | ((g) >> 5) | \ |
| 554 (((g) << 11) & 0xE000) | \ |
| 555 (((b) << 5) & 0x1F00)) |
| 556 |
| 557 #define PACK_TWO_PIXELS_LE(l, r) ((r << 16) | l) |
| 558 #define PACK_TWO_PIXELS_BE(l, r) ((l << 16) | r) |
| 559 |
| 560 #define PACK_NEED_ALIGNMENT(ptr) (((size_t)(ptr)) & 3) |
| 561 |
| 562 #define WRITE_TWO_ALIGNED_PIXELS(addr, pixels) ((*(int *)(addr)) = pixels) |
| 563 |
| 564 #define DITHER_565_R(r, dither) ((r) + ((dither) & 0xFF)) |
| 565 #define DITHER_565_G(g, dither) ((g) + (((dither) & 0xFF) >> 1)) |
| 566 #define DITHER_565_B(b, dither) ((b) + ((dither) & 0xFF)) |
| 567 |
| 568 |
| 569 /* Declarations for ordered dithering |
| 570 * |
| 571 * We use a 4x4 ordered dither array packed into 32 bits. This array is |
| 572 * sufficent for dithering RGB888 to RGB565. |
| 573 */ |
| 574 |
| 575 #define DITHER_MASK 0x3 |
| 576 #define DITHER_ROTATE(x) (((x) << 24) | (((x) >> 8) & 0x00FFFFFF)) |
| 577 static const INT32 dither_matrix[4] = { |
| 578 0x0008020A, |
| 579 0x0C040E06, |
| 580 0x030B0109, |
| 581 0x0F070D05 |
| 582 }; |
| 583 |
| 584 |
| 585 static INLINE boolean is_big_endian(void) |
| 586 { |
| 587 int test_value = 1; |
| 588 if(*(char *)&test_value != 1) |
| 589 return TRUE; |
| 590 return FALSE; |
| 591 } |
| 592 |
| 593 |
| 594 /* Include inline routines for RGB565 conversion */ |
| 595 |
| 596 #define PACK_SHORT_565 PACK_SHORT_565_LE |
| 597 #define PACK_TWO_PIXELS PACK_TWO_PIXELS_LE |
| 598 #define ycc_rgb565_convert_internal ycc_rgb565_convert_le |
| 599 #define ycc_rgb565D_convert_internal ycc_rgb565D_convert_le |
| 600 #define rgb_rgb565_convert_internal rgb_rgb565_convert_le |
| 601 #define rgb_rgb565D_convert_internal rgb_rgb565D_convert_le |
| 602 #define gray_rgb565_convert_internal gray_rgb565_convert_le |
| 603 #define gray_rgb565D_convert_internal gray_rgb565D_convert_le |
| 604 #include "jdcol565.c" |
| 605 #undef PACK_SHORT_565 |
| 606 #undef PACK_TWO_PIXELS |
| 607 #undef ycc_rgb565_convert_internal |
| 608 #undef ycc_rgb565D_convert_internal |
| 609 #undef rgb_rgb565_convert_internal |
| 610 #undef rgb_rgb565D_convert_internal |
| 611 #undef gray_rgb565_convert_internal |
| 612 #undef gray_rgb565D_convert_internal |
| 613 |
| 614 #define PACK_SHORT_565 PACK_SHORT_565_BE |
| 615 #define PACK_TWO_PIXELS PACK_TWO_PIXELS_BE |
| 616 #define ycc_rgb565_convert_internal ycc_rgb565_convert_be |
| 617 #define ycc_rgb565D_convert_internal ycc_rgb565D_convert_be |
| 618 #define rgb_rgb565_convert_internal rgb_rgb565_convert_be |
| 619 #define rgb_rgb565D_convert_internal rgb_rgb565D_convert_be |
| 620 #define gray_rgb565_convert_internal gray_rgb565_convert_be |
| 621 #define gray_rgb565D_convert_internal gray_rgb565D_convert_be |
| 622 #include "jdcol565.c" |
| 623 #undef PACK_SHORT_565 |
| 624 #undef PACK_TWO_PIXELS |
| 625 #undef ycc_rgb565_convert_internal |
| 626 #undef ycc_rgb565D_convert_internal |
| 627 #undef rgb_rgb565_convert_internal |
| 628 #undef rgb_rgb565D_convert_internal |
| 629 #undef gray_rgb565_convert_internal |
| 630 #undef gray_rgb565D_convert_internal |
| 631 |
| 632 |
| 633 METHODDEF(void) |
| 634 ycc_rgb565_convert (j_decompress_ptr cinfo, |
| 635 JSAMPIMAGE input_buf, JDIMENSION input_row, |
| 636 JSAMPARRAY output_buf, int num_rows) |
| 637 { |
| 638 if (is_big_endian()) |
| 639 ycc_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); |
| 640 else |
| 641 ycc_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); |
| 642 } |
| 643 |
| 644 |
| 645 METHODDEF(void) |
| 646 ycc_rgb565D_convert (j_decompress_ptr cinfo, |
| 647 JSAMPIMAGE input_buf, JDIMENSION input_row, |
| 648 JSAMPARRAY output_buf, int num_rows) |
| 649 { |
| 650 if (is_big_endian()) |
| 651 ycc_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); |
| 652 else |
| 653 ycc_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); |
| 654 } |
| 655 |
| 656 |
| 657 METHODDEF(void) |
| 658 rgb_rgb565_convert (j_decompress_ptr cinfo, |
| 659 JSAMPIMAGE input_buf, JDIMENSION input_row, |
| 660 JSAMPARRAY output_buf, int num_rows) |
| 661 { |
| 662 if (is_big_endian()) |
| 663 rgb_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); |
| 664 else |
| 665 rgb_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); |
| 666 } |
| 667 |
| 668 |
| 669 METHODDEF(void) |
| 670 rgb_rgb565D_convert (j_decompress_ptr cinfo, |
| 671 JSAMPIMAGE input_buf, JDIMENSION input_row, |
| 672 JSAMPARRAY output_buf, int num_rows) |
| 673 { |
| 674 if (is_big_endian()) |
| 675 rgb_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); |
| 676 else |
| 677 rgb_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); |
| 678 } |
| 679 |
| 680 |
| 681 METHODDEF(void) |
| 682 gray_rgb565_convert (j_decompress_ptr cinfo, |
| 683 JSAMPIMAGE input_buf, JDIMENSION input_row, |
| 684 JSAMPARRAY output_buf, int num_rows) |
| 685 { |
| 686 if (is_big_endian()) |
| 687 gray_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); |
| 688 else |
| 689 gray_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); |
| 690 } |
| 691 |
| 692 |
| 693 METHODDEF(void) |
| 694 gray_rgb565D_convert (j_decompress_ptr cinfo, |
| 695 JSAMPIMAGE input_buf, JDIMENSION input_row, |
| 696 JSAMPARRAY output_buf, int num_rows) |
| 697 { |
| 698 if (is_big_endian()) |
| 699 gray_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); |
| 700 else |
| 701 gray_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); |
| 702 } |
| 703 |
| 704 |
| 705 /* |
547 * Empty method for start_pass. | 706 * Empty method for start_pass. |
548 */ | 707 */ |
549 | 708 |
550 METHODDEF(void) | 709 METHODDEF(void) |
551 start_pass_dcolor (j_decompress_ptr cinfo) | 710 start_pass_dcolor (j_decompress_ptr cinfo) |
552 { | 711 { |
553 /* no work needed */ | 712 /* no work needed */ |
554 } | 713 } |
555 | 714 |
556 | 715 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 rgb_green[cinfo->out_color_space] == 1 && | 801 rgb_green[cinfo->out_color_space] == 1 && |
643 rgb_blue[cinfo->out_color_space] == 2 && | 802 rgb_blue[cinfo->out_color_space] == 2 && |
644 rgb_pixelsize[cinfo->out_color_space] == 3) | 803 rgb_pixelsize[cinfo->out_color_space] == 3) |
645 cconvert->pub.color_convert = null_convert; | 804 cconvert->pub.color_convert = null_convert; |
646 else | 805 else |
647 cconvert->pub.color_convert = rgb_rgb_convert; | 806 cconvert->pub.color_convert = rgb_rgb_convert; |
648 } else | 807 } else |
649 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); | 808 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); |
650 break; | 809 break; |
651 | 810 |
652 case JCS_CMYK: | 811 case JCS_RGB565: |
| 812 cinfo->out_color_components = 3; |
| 813 if (cinfo->dither_mode == JDITHER_NONE) { |
| 814 if (cinfo->jpeg_color_space == JCS_YCbCr) { |
| 815 if (jsimd_can_ycc_rgb565()) |
| 816 cconvert->pub.color_convert = jsimd_ycc_rgb565_convert; |
| 817 else { |
| 818 cconvert->pub.color_convert = ycc_rgb565_convert; |
| 819 build_ycc_rgb_table(cinfo); |
| 820 } |
| 821 } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { |
| 822 cconvert->pub.color_convert = gray_rgb565_convert; |
| 823 } else if (cinfo->jpeg_color_space == JCS_RGB) { |
| 824 cconvert->pub.color_convert = rgb_rgb565_convert; |
| 825 } else |
| 826 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); |
| 827 } else { |
| 828 /* only ordered dithering is supported */ |
| 829 if (cinfo->jpeg_color_space == JCS_YCbCr) { |
| 830 cconvert->pub.color_convert = ycc_rgb565D_convert; |
| 831 build_ycc_rgb_table(cinfo); |
| 832 } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { |
| 833 cconvert->pub.color_convert = gray_rgb565D_convert; |
| 834 } else if (cinfo->jpeg_color_space == JCS_RGB) { |
| 835 cconvert->pub.color_convert = rgb_rgb565D_convert; |
| 836 } else |
| 837 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); |
| 838 } |
| 839 break; |
| 840 |
| 841 case JCS_CMYK: |
653 cinfo->out_color_components = 4; | 842 cinfo->out_color_components = 4; |
654 if (cinfo->jpeg_color_space == JCS_YCCK) { | 843 if (cinfo->jpeg_color_space == JCS_YCCK) { |
655 cconvert->pub.color_convert = ycck_cmyk_convert; | 844 cconvert->pub.color_convert = ycck_cmyk_convert; |
656 build_ycc_rgb_table(cinfo); | 845 build_ycc_rgb_table(cinfo); |
657 } else if (cinfo->jpeg_color_space == JCS_CMYK) { | 846 } else if (cinfo->jpeg_color_space == JCS_CMYK) { |
658 cconvert->pub.color_convert = null_convert; | 847 cconvert->pub.color_convert = null_convert; |
659 } else | 848 } else |
660 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); | 849 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); |
661 break; | 850 break; |
662 | 851 |
663 default: | 852 default: |
664 /* Permit null conversion to same output space */ | 853 /* Permit null conversion to same output space */ |
665 if (cinfo->out_color_space == cinfo->jpeg_color_space) { | 854 if (cinfo->out_color_space == cinfo->jpeg_color_space) { |
666 cinfo->out_color_components = cinfo->num_components; | 855 cinfo->out_color_components = cinfo->num_components; |
667 cconvert->pub.color_convert = null_convert; | 856 cconvert->pub.color_convert = null_convert; |
668 } else /* unsupported non-null conversion */ | 857 } else /* unsupported non-null conversion */ |
669 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); | 858 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); |
670 break; | 859 break; |
671 } | 860 } |
672 | 861 |
673 if (cinfo->quantize_colors) | 862 if (cinfo->quantize_colors) |
674 cinfo->output_components = 1; /* single colormapped output component */ | 863 cinfo->output_components = 1; /* single colormapped output component */ |
675 else | 864 else |
676 cinfo->output_components = cinfo->out_color_components; | 865 cinfo->output_components = cinfo->out_color_components; |
677 } | 866 } |
OLD | NEW |