OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "../../../../third_party/lcms2-2.6/include/lcms2.h" | 10 #include "../../../../third_party/lcms2-2.6/include/lcms2.h" |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 image->comps[1].prec = 16; | 580 image->comps[1].prec = 16; |
581 image->comps[2].prec = 16; | 581 image->comps[2].prec = 16; |
582 return; | 582 return; |
583 } | 583 } |
584 } | 584 } |
585 class CJPX_Decoder | 585 class CJPX_Decoder |
586 { | 586 { |
587 public: | 587 public: |
588 CJPX_Decoder(); | 588 CJPX_Decoder(); |
589 ~CJPX_Decoder(); | 589 ~CJPX_Decoder(); |
590 FX_BOOL» Init(const unsigned char* src_data, int src_size); | 590 bool» Init(const unsigned char* src_data, int src_size); |
591 void GetInfo(FX_DWORD& width, FX_DWORD& height, FX_DWORD& codestream_
nComps, FX_DWORD& output_nComps); | 591 void GetInfo(FX_DWORD& width, FX_DWORD& height, FX_DWORD& codestream_
nComps, FX_DWORD& output_nComps); |
592 FX_BOOL» Decode(uint8_t* dest_buf, int pitch, FX_BOOL bTranslateColor, ui
nt8_t* offsets); | 592 bool» Decode(uint8_t* dest_buf, int pitch, bool bTranslateColor, uint8
_t* offsets); |
593 const uint8_t* m_SrcData; | 593 const uint8_t* m_SrcData; |
594 int m_SrcSize; | 594 int m_SrcSize; |
595 opj_image_t *image; | 595 opj_image_t *image; |
596 opj_codec_t* l_codec; | 596 opj_codec_t* l_codec; |
597 opj_stream_t *l_stream; | 597 opj_stream_t *l_stream; |
598 FX_BOOL m_useColorSpace; | 598 bool m_useColorSpace; |
599 }; | 599 }; |
600 CJPX_Decoder::CJPX_Decoder(): image(NULL), l_codec(NULL), l_stream(NULL), m_useC
olorSpace(FALSE) | 600 CJPX_Decoder::CJPX_Decoder(): image(NULL), l_codec(NULL), l_stream(NULL), m_useC
olorSpace(false) |
601 { | 601 { |
602 } | 602 } |
603 CJPX_Decoder::~CJPX_Decoder() | 603 CJPX_Decoder::~CJPX_Decoder() |
604 { | 604 { |
605 if(l_codec) { | 605 if(l_codec) { |
606 opj_destroy_codec(l_codec); | 606 opj_destroy_codec(l_codec); |
607 } | 607 } |
608 if(l_stream) { | 608 if(l_stream) { |
609 opj_stream_destroy(l_stream); | 609 opj_stream_destroy(l_stream); |
610 } | 610 } |
611 if(image) { | 611 if(image) { |
612 opj_image_destroy(image); | 612 opj_image_destroy(image); |
613 } | 613 } |
614 } | 614 } |
615 FX_BOOL CJPX_Decoder::Init(const unsigned char* src_data, int src_size) | 615 bool CJPX_Decoder::Init(const unsigned char* src_data, int src_size) |
616 { | 616 { |
617 static const unsigned char szJP2Header[] = { 0x00, 0x00, 0x00, 0x0c, 0x6a, 0
x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a }; | 617 static const unsigned char szJP2Header[] = { 0x00, 0x00, 0x00, 0x0c, 0x6a, 0
x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a }; |
618 if (!src_data || src_size < sizeof(szJP2Header)) { | 618 if (!src_data || src_size < sizeof(szJP2Header)) { |
619 return FALSE; | 619 return false; |
620 } | 620 } |
621 image = NULL; | 621 image = NULL; |
622 m_SrcData = src_data; | 622 m_SrcData = src_data; |
623 m_SrcSize = src_size; | 623 m_SrcSize = src_size; |
624 DecodeData srcData(const_cast<unsigned char*>(src_data), src_size); | 624 DecodeData srcData(const_cast<unsigned char*>(src_data), src_size); |
625 l_stream = fx_opj_stream_create_memory_stream(&srcData, OPJ_J2K_STREAM_CHUNK
_SIZE, 1); | 625 l_stream = fx_opj_stream_create_memory_stream(&srcData, OPJ_J2K_STREAM_CHUNK
_SIZE, 1); |
626 if (l_stream == NULL) { | 626 if (l_stream == NULL) { |
627 return FALSE; | 627 return false; |
628 } | 628 } |
629 opj_dparameters_t parameters; | 629 opj_dparameters_t parameters; |
630 opj_set_default_decoder_parameters(¶meters); | 630 opj_set_default_decoder_parameters(¶meters); |
631 parameters.decod_format = 0; | 631 parameters.decod_format = 0; |
632 parameters.cod_format = 3; | 632 parameters.cod_format = 3; |
633 if(FXSYS_memcmp(m_SrcData, szJP2Header, sizeof(szJP2Header)) == 0) { | 633 if(FXSYS_memcmp(m_SrcData, szJP2Header, sizeof(szJP2Header)) == 0) { |
634 l_codec = opj_create_decompress(OPJ_CODEC_JP2); | 634 l_codec = opj_create_decompress(OPJ_CODEC_JP2); |
635 parameters.decod_format = 1; | 635 parameters.decod_format = 1; |
636 } else { | 636 } else { |
637 l_codec = opj_create_decompress(OPJ_CODEC_J2K); | 637 l_codec = opj_create_decompress(OPJ_CODEC_J2K); |
638 } | 638 } |
639 if(!l_codec) { | 639 if(!l_codec) { |
640 return FALSE; | 640 return false; |
641 } | 641 } |
642 opj_set_info_handler(l_codec, fx_info_callback, 00); | 642 opj_set_info_handler(l_codec, fx_info_callback, 00); |
643 opj_set_warning_handler(l_codec, fx_warning_callback, 00); | 643 opj_set_warning_handler(l_codec, fx_warning_callback, 00); |
644 opj_set_error_handler(l_codec, fx_error_callback, 00); | 644 opj_set_error_handler(l_codec, fx_error_callback, 00); |
645 if ( !opj_setup_decoder(l_codec, ¶meters) ) { | 645 if ( !opj_setup_decoder(l_codec, ¶meters) ) { |
646 return FALSE; | 646 return false; |
647 } | 647 } |
648 if(! opj_read_header(l_stream, l_codec, &image)) { | 648 if(! opj_read_header(l_stream, l_codec, &image)) { |
649 image = NULL; | 649 image = NULL; |
650 return FALSE; | 650 return false; |
651 } | 651 } |
652 if (!parameters.nb_tile_to_decode) { | 652 if (!parameters.nb_tile_to_decode) { |
653 if (!opj_set_decode_area(l_codec, image, parameters.DA_x0, | 653 if (!opj_set_decode_area(l_codec, image, parameters.DA_x0, |
654 parameters.DA_y0, parameters.DA_x1, paramete
rs.DA_y1)) { | 654 parameters.DA_y0, parameters.DA_x1, paramete
rs.DA_y1)) { |
655 opj_image_destroy(image); | 655 opj_image_destroy(image); |
656 image = NULL; | 656 image = NULL; |
657 return FALSE; | 657 return false; |
658 } | 658 } |
659 if (!(opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_codec
, l_stream))) { | 659 if (!(opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_codec
, l_stream))) { |
660 opj_image_destroy(image); | 660 opj_image_destroy(image); |
661 image = NULL; | 661 image = NULL; |
662 return FALSE; | 662 return false; |
663 } | 663 } |
664 } else { | 664 } else { |
665 if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_inde
x)) { | 665 if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_inde
x)) { |
666 return FALSE; | 666 return false; |
667 } | 667 } |
668 } | 668 } |
669 opj_stream_destroy(l_stream); | 669 opj_stream_destroy(l_stream); |
670 l_stream = NULL; | 670 l_stream = NULL; |
671 if( image->color_space != OPJ_CLRSPC_SYCC | 671 if( image->color_space != OPJ_CLRSPC_SYCC |
672 && image->numcomps == 3 && image->comps[0].dx == image->comps[0].dy | 672 && image->numcomps == 3 && image->comps[0].dx == image->comps[0].dy |
673 && image->comps[1].dx != 1 ) { | 673 && image->comps[1].dx != 1 ) { |
674 image->color_space = OPJ_CLRSPC_SYCC; | 674 image->color_space = OPJ_CLRSPC_SYCC; |
675 } else if (image->numcomps <= 2) { | 675 } else if (image->numcomps <= 2) { |
676 image->color_space = OPJ_CLRSPC_GRAY; | 676 image->color_space = OPJ_CLRSPC_GRAY; |
677 } | 677 } |
678 if(image->color_space == OPJ_CLRSPC_SYCC) { | 678 if(image->color_space == OPJ_CLRSPC_SYCC) { |
679 color_sycc_to_rgb(image); | 679 color_sycc_to_rgb(image); |
680 } | 680 } |
681 if(image->icc_profile_buf) { | 681 if(image->icc_profile_buf) { |
682 FX_Free(image->icc_profile_buf); | 682 FX_Free(image->icc_profile_buf); |
683 image->icc_profile_buf = NULL; | 683 image->icc_profile_buf = NULL; |
684 image->icc_profile_len = 0; | 684 image->icc_profile_len = 0; |
685 } | 685 } |
686 if(!image) { | 686 if(!image) { |
687 return FALSE; | 687 return false; |
688 } | 688 } |
689 return TRUE; | 689 return true; |
690 } | 690 } |
691 void CJPX_Decoder::GetInfo(FX_DWORD& width, FX_DWORD& height, FX_DWORD& codestre
am_nComps, FX_DWORD& output_nComps) | 691 void CJPX_Decoder::GetInfo(FX_DWORD& width, FX_DWORD& height, FX_DWORD& codestre
am_nComps, FX_DWORD& output_nComps) |
692 { | 692 { |
693 width = (FX_DWORD)image->x1; | 693 width = (FX_DWORD)image->x1; |
694 height = (FX_DWORD)image->y1; | 694 height = (FX_DWORD)image->y1; |
695 output_nComps = codestream_nComps = (FX_DWORD)image->numcomps; | 695 output_nComps = codestream_nComps = (FX_DWORD)image->numcomps; |
696 } | 696 } |
697 FX_BOOL CJPX_Decoder::Decode(uint8_t* dest_buf, int pitch, FX_BOOL bTranslateCol
or, uint8_t* offsets) | 697 bool CJPX_Decoder::Decode(uint8_t* dest_buf, int pitch, bool bTranslateColor, ui
nt8_t* offsets) |
698 { | 698 { |
699 int i, wid, hei, row, col, channel, src; | 699 int i, wid, hei, row, col, channel, src; |
700 uint8_t* pChannel; | 700 uint8_t* pChannel; |
701 uint8_t* pScanline; | 701 uint8_t* pScanline; |
702 uint8_t* pPixel; | 702 uint8_t* pPixel; |
703 | 703 |
704 if(image->comps[0].w != image->x1 || image->comps[0].h != image->y1) { | 704 if(image->comps[0].w != image->x1 || image->comps[0].h != image->y1) { |
705 return FALSE; | 705 return false; |
706 } | 706 } |
707 if(pitch < (int)(image->comps[0].w * 8 * image->numcomps + 31) >> 5 << 2) { | 707 if(pitch < (int)(image->comps[0].w * 8 * image->numcomps + 31) >> 5 << 2) { |
708 return FALSE; | 708 return false; |
709 } | 709 } |
710 FXSYS_memset(dest_buf, 0xff, image->y1 * pitch); | 710 FXSYS_memset(dest_buf, 0xff, image->y1 * pitch); |
711 uint8_t** channel_bufs = FX_Alloc(uint8_t*, image->numcomps); | 711 uint8_t** channel_bufs = FX_Alloc(uint8_t*, image->numcomps); |
712 FX_BOOL result = FALSE; | 712 bool result = false; |
713 int* adjust_comps = FX_Alloc(int, image->numcomps); | 713 int* adjust_comps = FX_Alloc(int, image->numcomps); |
714 for (i = 0; i < (int)image->numcomps; i ++) { | 714 for (i = 0; i < (int)image->numcomps; i ++) { |
715 channel_bufs[i] = dest_buf + offsets[i]; | 715 channel_bufs[i] = dest_buf + offsets[i]; |
716 adjust_comps[i] = image->comps[i].prec - 8; | 716 adjust_comps[i] = image->comps[i].prec - 8; |
717 if(i > 0) { | 717 if(i > 0) { |
718 if(image->comps[i].dx != image->comps[i - 1].dx | 718 if(image->comps[i].dx != image->comps[i - 1].dx |
719 || image->comps[i].dy != image->comps[i - 1].dy | 719 || image->comps[i].dy != image->comps[i - 1].dy |
720 || image->comps[i].prec != image->comps[i - 1].prec) { | 720 || image->comps[i].prec != image->comps[i - 1].prec) { |
721 goto done; | 721 goto done; |
722 } | 722 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 tmpPixel = 255; | 758 tmpPixel = 255; |
759 } else if (tmpPixel < 0) { | 759 } else if (tmpPixel < 0) { |
760 tmpPixel = 0; | 760 tmpPixel = 0; |
761 } | 761 } |
762 *pPixel = (uint8_t)tmpPixel; | 762 *pPixel = (uint8_t)tmpPixel; |
763 } | 763 } |
764 } | 764 } |
765 } | 765 } |
766 } | 766 } |
767 } | 767 } |
768 result = TRUE; | 768 result = true; |
769 | 769 |
770 done: | 770 done: |
771 FX_Free(channel_bufs); | 771 FX_Free(channel_bufs); |
772 FX_Free(adjust_comps); | 772 FX_Free(adjust_comps); |
773 return result; | 773 return result; |
774 } | 774 } |
775 void initialize_transition_table(); | 775 void initialize_transition_table(); |
776 void initialize_significance_luts(); | 776 void initialize_significance_luts(); |
777 void initialize_sign_lut(); | 777 void initialize_sign_lut(); |
778 CCodec_JpxModule::CCodec_JpxModule() | 778 CCodec_JpxModule::CCodec_JpxModule() |
779 { | 779 { |
780 } | 780 } |
781 void* CCodec_JpxModule::CreateDecoder(const uint8_t* src_buf, FX_DWORD src_size
, FX_BOOL useColorSpace) | 781 void* CCodec_JpxModule::CreateDecoder(const uint8_t* src_buf, FX_DWORD src_size
, bool useColorSpace) |
782 { | 782 { |
783 CJPX_Decoder* pDecoder = new CJPX_Decoder; | 783 CJPX_Decoder* pDecoder = new CJPX_Decoder; |
784 pDecoder->m_useColorSpace = useColorSpace; | 784 pDecoder->m_useColorSpace = useColorSpace; |
785 if (!pDecoder->Init(src_buf, src_size)) { | 785 if (!pDecoder->Init(src_buf, src_size)) { |
786 delete pDecoder; | 786 delete pDecoder; |
787 return NULL; | 787 return NULL; |
788 } | 788 } |
789 return pDecoder; | 789 return pDecoder; |
790 } | 790 } |
791 void CCodec_JpxModule::GetImageInfo(void* ctx, FX_DWORD& width, FX_DWORD& height
, | 791 void CCodec_JpxModule::GetImageInfo(void* ctx, FX_DWORD& width, FX_DWORD& height
, |
792 FX_DWORD& codestream_nComps, FX_DWORD& outpu
t_nComps) | 792 FX_DWORD& codestream_nComps, FX_DWORD& outpu
t_nComps) |
793 { | 793 { |
794 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; | 794 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; |
795 pDecoder->GetInfo(width, height, codestream_nComps, output_nComps); | 795 pDecoder->GetInfo(width, height, codestream_nComps, output_nComps); |
796 } | 796 } |
797 FX_BOOL CCodec_JpxModule::Decode(void* ctx, uint8_t* dest_data, int pitch, FX_BO
OL bTranslateColor, uint8_t* offsets) | 797 bool CCodec_JpxModule::Decode(void* ctx, uint8_t* dest_data, int pitch, bool bTr
anslateColor, uint8_t* offsets) |
798 { | 798 { |
799 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; | 799 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; |
800 return pDecoder->Decode(dest_data, pitch, bTranslateColor, offsets); | 800 return pDecoder->Decode(dest_data, pitch, bTranslateColor, offsets); |
801 } | 801 } |
802 void CCodec_JpxModule::DestroyDecoder(void* ctx) | 802 void CCodec_JpxModule::DestroyDecoder(void* ctx) |
803 { | 803 { |
804 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; | 804 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; |
805 delete pDecoder; | 805 delete pDecoder; |
806 } | 806 } |
OLD | NEW |