| 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 |