| 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 "../../../include/fxcodec/fx_codec.h" | 7 #include "../../../include/fxcodec/fx_codec.h" |
| 8 #include "codec_int.h" | 8 #include "codec_int.h" |
| 9 #include "../fx_libopenjpeg/libopenjpeg20/openjpeg.h" | 9 #include "../fx_libopenjpeg/libopenjpeg20/openjpeg.h" |
| 10 #include "../lcms2/include/fx_lcms2.h" | 10 #include "../lcms2/include/fx_lcms2.h" |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 if(l_stream) { | 575 if(l_stream) { |
| 576 opj_stream_destroy(l_stream); | 576 opj_stream_destroy(l_stream); |
| 577 } | 577 } |
| 578 if(image) { | 578 if(image) { |
| 579 opj_image_destroy(image); | 579 opj_image_destroy(image); |
| 580 } | 580 } |
| 581 } | 581 } |
| 582 FX_BOOL CJPX_Decoder::Init(const unsigned char* src_data, int src_size) | 582 FX_BOOL CJPX_Decoder::Init(const unsigned char* src_data, int src_size) |
| 583 { | 583 { |
| 584 opj_dparameters_t parameters; | 584 opj_dparameters_t parameters; |
| 585 try { | 585 image = NULL; |
| 586 m_SrcData = src_data; |
| 587 m_SrcSize = src_size; |
| 588 decodeData srcData; |
| 589 srcData.offset = 0; |
| 590 srcData.src_size = src_size; |
| 591 srcData.src_data = src_data; |
| 592 l_stream = fx_opj_stream_create_memory_stream(&srcData, OPJ_J2K_STREAM_CHUNK
_SIZE, 1); |
| 593 if (l_stream == NULL) { |
| 594 return FALSE; |
| 595 } |
| 596 opj_set_default_decoder_parameters(¶meters); |
| 597 parameters.decod_format = 0; |
| 598 parameters.cod_format = 3; |
| 599 if(FXSYS_memcmp32(m_SrcData, "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x
0a", 12) == 0) { |
| 600 l_codec = opj_create_decompress(OPJ_CODEC_JP2); |
| 601 parameters.decod_format = 1; |
| 602 } else { |
| 603 l_codec = opj_create_decompress(OPJ_CODEC_J2K); |
| 604 } |
| 605 if(!l_codec) { |
| 606 return FALSE; |
| 607 } |
| 608 opj_set_info_handler(l_codec, fx_info_callback, 00); |
| 609 opj_set_warning_handler(l_codec, fx_warning_callback, 00); |
| 610 opj_set_error_handler(l_codec, fx_error_callback, 00); |
| 611 if ( !opj_setup_decoder(l_codec, ¶meters) ) { |
| 612 return FALSE; |
| 613 } |
| 614 if(! opj_read_header(l_stream, l_codec, &image)) { |
| 586 image = NULL; | 615 image = NULL; |
| 587 m_SrcData = src_data; | 616 return FALSE; |
| 588 m_SrcSize = src_size; | 617 } |
| 589 decodeData srcData; | 618 if(this->m_useColorSpace) { |
| 590 srcData.offset = 0; | 619 image->useColorSpace = 1; |
| 591 srcData.src_size = src_size; | 620 } else { |
| 592 srcData.src_data = src_data; | 621 image->useColorSpace = 0; |
| 593 l_stream = fx_opj_stream_create_memory_stream(&srcData, OPJ_J2K_STREAM_C
HUNK_SIZE, 1); | 622 } |
| 594 if (l_stream == NULL) { | 623 if (!parameters.nb_tile_to_decode) { |
| 595 return FALSE; | 624 if (!opj_set_decode_area(l_codec, image, parameters.DA_x0, |
| 596 } | 625 parameters.DA_y0, parameters.DA_x1, paramete
rs.DA_y1)) { |
| 597 opj_set_default_decoder_parameters(¶meters); | 626 opj_image_destroy(image); |
| 598 parameters.decod_format = 0; | |
| 599 parameters.cod_format = 3; | |
| 600 if(FXSYS_memcmp32(m_SrcData, "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x
87\x0a", 12) == 0) { | |
| 601 l_codec = opj_create_decompress(OPJ_CODEC_JP2); | |
| 602 parameters.decod_format = 1; | |
| 603 } else { | |
| 604 l_codec = opj_create_decompress(OPJ_CODEC_J2K); | |
| 605 } | |
| 606 if(!l_codec) { | |
| 607 return FALSE; | |
| 608 } | |
| 609 opj_set_info_handler(l_codec, fx_info_callback, 00); | |
| 610 opj_set_warning_handler(l_codec, fx_warning_callback, 00); | |
| 611 opj_set_error_handler(l_codec, fx_error_callback, 00); | |
| 612 if ( !opj_setup_decoder(l_codec, ¶meters) ) { | |
| 613 return FALSE; | |
| 614 } | |
| 615 if(! opj_read_header(l_stream, l_codec, &image)) { | |
| 616 image = NULL; | 627 image = NULL; |
| 617 return FALSE; | 628 return FALSE; |
| 618 } | 629 } |
| 619 if(this->m_useColorSpace) { | 630 if (!(opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_codec
,» l_stream))) { |
| 620 image->useColorSpace = 1; | 631 opj_image_destroy(image); |
| 621 } else { | 632 image = NULL; |
| 622 image->useColorSpace = 0; | |
| 623 } | |
| 624 if (!parameters.nb_tile_to_decode) { | |
| 625 if (!opj_set_decode_area(l_codec, image, parameters.DA_x0, | |
| 626 parameters.DA_y0, parameters.DA_x1, paramet
ers.DA_y1)) { | |
| 627 opj_image_destroy(image); | |
| 628 image = NULL; | |
| 629 return FALSE; | |
| 630 } | |
| 631 if (!(opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_c
odec,» l_stream))) { | |
| 632 opj_image_destroy(image); | |
| 633 image = NULL; | |
| 634 return FALSE; | |
| 635 } | |
| 636 } else { | |
| 637 if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_
index)) { | |
| 638 return FALSE; | |
| 639 } | |
| 640 } | |
| 641 opj_stream_destroy(l_stream); | |
| 642 l_stream = NULL; | |
| 643 if( image->color_space != OPJ_CLRSPC_SYCC | |
| 644 && image->numcomps == 3 && image->comps[0].dx == image->comps[0]
.dy | |
| 645 && image->comps[1].dx != 1 ) { | |
| 646 image->color_space = OPJ_CLRSPC_SYCC; | |
| 647 } else if (image->numcomps <= 2) { | |
| 648 image->color_space = OPJ_CLRSPC_GRAY; | |
| 649 } | |
| 650 if(image->color_space == OPJ_CLRSPC_SYCC) { | |
| 651 color_sycc_to_rgb(image); | |
| 652 } | |
| 653 if(image->icc_profile_buf && !image->useColorSpace) { | |
| 654 FX_Free(image->icc_profile_buf); | |
| 655 image->icc_profile_buf = NULL; | |
| 656 image->icc_profile_len = 0; | |
| 657 } | |
| 658 if(!image) { | |
| 659 return FALSE; | 633 return FALSE; |
| 660 } | 634 } |
| 661 } catch (...) { | 635 } else { |
| 636 if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_inde
x)) { |
| 637 return FALSE; |
| 638 } |
| 639 } |
| 640 opj_stream_destroy(l_stream); |
| 641 l_stream = NULL; |
| 642 if( image->color_space != OPJ_CLRSPC_SYCC |
| 643 && image->numcomps == 3 && image->comps[0].dx == image->comps[0].dy |
| 644 && image->comps[1].dx != 1 ) { |
| 645 image->color_space = OPJ_CLRSPC_SYCC; |
| 646 } else if (image->numcomps <= 2) { |
| 647 image->color_space = OPJ_CLRSPC_GRAY; |
| 648 } |
| 649 if(image->color_space == OPJ_CLRSPC_SYCC) { |
| 650 color_sycc_to_rgb(image); |
| 651 } |
| 652 if(image->icc_profile_buf && !image->useColorSpace) { |
| 653 FX_Free(image->icc_profile_buf); |
| 654 image->icc_profile_buf = NULL; |
| 655 image->icc_profile_len = 0; |
| 656 } |
| 657 if(!image) { |
| 662 return FALSE; | 658 return FALSE; |
| 663 } | 659 } |
| 664 return TRUE; | 660 return TRUE; |
| 665 } | 661 } |
| 666 void CJPX_Decoder::GetInfo(FX_DWORD& width, FX_DWORD& height, FX_DWORD& codestre
am_nComps, FX_DWORD& output_nComps) | 662 void CJPX_Decoder::GetInfo(FX_DWORD& width, FX_DWORD& height, FX_DWORD& codestre
am_nComps, FX_DWORD& output_nComps) |
| 667 { | 663 { |
| 668 width = (FX_DWORD)image->x1; | 664 width = (FX_DWORD)image->x1; |
| 669 height = (FX_DWORD)image->y1; | 665 height = (FX_DWORD)image->y1; |
| 670 output_nComps = codestream_nComps = (FX_DWORD)image->numcomps; | 666 output_nComps = codestream_nComps = (FX_DWORD)image->numcomps; |
| 671 } | 667 } |
| 672 FX_BOOL CJPX_Decoder::Decode(FX_LPBYTE dest_buf, int pitch, FX_BOOL bTranslateCo
lor, FX_LPBYTE offsets) | 668 FX_BOOL CJPX_Decoder::Decode(FX_LPBYTE dest_buf, int pitch, FX_BOOL bTranslateCo
lor, FX_LPBYTE offsets) |
| 673 { | 669 { |
| 674 FX_BYTE** channel_bufs; | 670 FX_BYTE** channel_bufs; |
| 675 int* adjust_comps; | 671 int* adjust_comps; |
| 676 int i, wid, hei, row, col, channel, src; | 672 int i, wid, hei, row, col, channel, src; |
| 677 FX_BOOL flag; | 673 FX_BOOL flag; |
| 678 FX_LPBYTE pChannel, pScanline, pPixel; | 674 FX_LPBYTE pChannel, pScanline, pPixel; |
| 679 try { | 675 |
| 680 if(image->comps[0].w != image->x1 || image->comps[0].h != image->y1) { | 676 if(image->comps[0].w != image->x1 || image->comps[0].h != image->y1) { |
| 681 return FALSE; | 677 return FALSE; |
| 678 } |
| 679 if(pitch < (int)(image->comps[0].w * 8 * image->numcomps + 31) >> 5 << 2) { |
| 680 return FALSE; |
| 681 } |
| 682 FXSYS_memset8(dest_buf, 0xff, image->y1 * pitch); |
| 683 channel_bufs = FX_Alloc(FX_BYTE*, image->numcomps); |
| 684 if (channel_bufs == NULL) { |
| 685 return FALSE; |
| 686 } |
| 687 adjust_comps = FX_Alloc(int, image->numcomps); |
| 688 if (adjust_comps == NULL) { |
| 689 FX_Free(channel_bufs); |
| 690 return FALSE; |
| 691 } |
| 692 flag = TRUE; |
| 693 for (i = 0; i < (int)image->numcomps; i ++) { |
| 694 channel_bufs[i] = dest_buf + offsets[i]; |
| 695 adjust_comps[i] = image->comps[i].prec - 8; |
| 696 if(i > 0) { |
| 697 if(image->comps[i].dx != image->comps[i - 1].dx |
| 698 || image->comps[i].dy != image->comps[i - 1].dy |
| 699 || image->comps[i].prec != image->comps[i - 1].prec) { |
| 700 flag = FALSE; |
| 701 goto failed; |
| 702 } |
| 682 } | 703 } |
| 683 if(pitch < (int)(image->comps[0].w * 8 * image->numcomps + 31) >> 5 << 2
) { | 704 } |
| 684 return FALSE; | 705 wid = image->comps[0].w; |
| 685 } | 706 hei = image->comps[0].h; |
| 686 FXSYS_memset8(dest_buf, 0xff, image->y1 * pitch); | 707 for (channel = 0; channel < (int)image->numcomps; channel++) { |
| 687 channel_bufs = FX_Alloc(FX_BYTE*, image->numcomps); | 708 pChannel = channel_bufs[channel]; |
| 688 if (channel_bufs == NULL) { | 709 if(adjust_comps[channel] < 0) { |
| 689 return FALSE; | 710 for(row = 0; row < hei; row++) { |
| 690 } | 711 pScanline = pChannel + row * pitch; |
| 691 adjust_comps = FX_Alloc(int, image->numcomps); | 712 for (col = 0; col < wid; col++) { |
| 692 if (adjust_comps == NULL) { | 713 pPixel = pScanline + col * image->numcomps; |
| 693 FX_Free(channel_bufs); | 714 src = image->comps[channel].data[row * wid + col]; |
| 694 return FALSE; | 715 src += image->comps[channel].sgnd ? 1 << (image->comps[chann
el].prec - 1) : 0; |
| 695 } | 716 if (adjust_comps[channel] > 0) { |
| 696 flag = TRUE; | 717 *pPixel = 0; |
| 697 for (i = 0; i < (int)image->numcomps; i ++) { | 718 } else { |
| 698 channel_bufs[i] = dest_buf + offsets[i]; | 719 *pPixel = (FX_BYTE)(src << -adjust_comps[channel]); |
| 699 adjust_comps[i] = image->comps[i].prec - 8; | 720 } |
| 700 if(i > 0) { | |
| 701 if(image->comps[i].dx != image->comps[i - 1].dx | |
| 702 || image->comps[i].dy != image->comps[i - 1].dy | |
| 703 || image->comps[i].prec != image->comps[i - 1].prec) { | |
| 704 flag = FALSE; | |
| 705 goto failed; | |
| 706 } | 721 } |
| 707 } | 722 } |
| 708 } | 723 } else { |
| 709 wid = image->comps[0].w; | 724 for(row = 0; row < hei; row++) { |
| 710 hei = image->comps[0].h; | 725 pScanline = pChannel + row * pitch; |
| 711 for (channel = 0; channel < (int)image->numcomps; channel++) { | 726 for (col = 0; col < wid; col++) { |
| 712 pChannel = channel_bufs[channel]; | 727 pPixel = pScanline + col * image->numcomps; |
| 713 if(adjust_comps[channel] < 0) { | 728 if (!image->comps[channel].data) { |
| 714 for(row = 0; row < hei; row++) { | 729 continue; |
| 715 pScanline = pChannel + row * pitch; | 730 } |
| 716 for (col = 0; col < wid; col++) { | 731 src = image->comps[channel].data[row * wid + col]; |
| 717 pPixel = pScanline + col * image->numcomps; | 732 src += image->comps[channel].sgnd ? 1 << (image->comps[chann
el].prec - 1) : 0; |
| 718 src = image->comps[channel].data[row * wid + col]; | 733 if (adjust_comps[channel] - 1 < 0) { |
| 719 src += image->comps[channel].sgnd ? 1 << (image->comps[c
hannel].prec - 1) : 0; | 734 *pPixel = (FX_BYTE)((src >> adjust_comps[channel])); |
| 720 if (adjust_comps[channel] > 0) { | 735 } else { |
| 721 *pPixel = 0; | 736 int tmpPixel = (src >> adjust_comps[channel]) + ((src >>
(adjust_comps[channel] - 1)) % 2); |
| 722 } else { | 737 if (tmpPixel > 255) { |
| 723 *pPixel = (FX_BYTE)(src << -adjust_comps[channel]); | 738 tmpPixel = 255; |
| 739 } else if (tmpPixel < 0) { |
| 740 tmpPixel = 0; |
| 724 } | 741 } |
| 725 } | 742 *pPixel = (FX_BYTE)tmpPixel; |
| 726 } | |
| 727 } else { | |
| 728 for(row = 0; row < hei; row++) { | |
| 729 pScanline = pChannel + row * pitch; | |
| 730 for (col = 0; col < wid; col++) { | |
| 731 pPixel = pScanline + col * image->numcomps; | |
| 732 if (!image->comps[channel].data) { | |
| 733 continue; | |
| 734 } | |
| 735 src = image->comps[channel].data[row * wid + col]; | |
| 736 src += image->comps[channel].sgnd ? 1 << (image->comps[c
hannel].prec - 1) : 0; | |
| 737 if (adjust_comps[channel] - 1 < 0) { | |
| 738 *pPixel = (FX_BYTE)((src >> adjust_comps[channel])); | |
| 739 } else { | |
| 740 int tmpPixel = (src >> adjust_comps[channel]) + ((sr
c >> (adjust_comps[channel] - 1)) % 2); | |
| 741 if (tmpPixel > 255) { | |
| 742 tmpPixel = 255; | |
| 743 } else if (tmpPixel < 0) { | |
| 744 tmpPixel = 0; | |
| 745 } | |
| 746 *pPixel = (FX_BYTE)tmpPixel; | |
| 747 } | |
| 748 } | 743 } |
| 749 } | 744 } |
| 750 } | 745 } |
| 751 } | 746 } |
| 752 } catch (...) { | |
| 753 if (channel_bufs) { | |
| 754 FX_Free(channel_bufs); | |
| 755 } | |
| 756 FX_Free(adjust_comps); | |
| 757 return FALSE; | |
| 758 } | 747 } |
| 748 |
| 759 FX_Free(channel_bufs); | 749 FX_Free(channel_bufs); |
| 760 FX_Free(adjust_comps); | 750 FX_Free(adjust_comps); |
| 761 return TRUE; | 751 return TRUE; |
| 762 failed: | 752 failed: |
| 763 FX_Free(channel_bufs); | 753 FX_Free(channel_bufs); |
| 764 FX_Free(adjust_comps); | 754 FX_Free(adjust_comps); |
| 765 return FALSE; | 755 return FALSE; |
| 766 } | 756 } |
| 767 void initialize_transition_table(); | 757 void initialize_transition_table(); |
| 768 void initialize_significance_luts(); | 758 void initialize_significance_luts(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 792 FX_BOOL CCodec_JpxModule::Decode(void* ctx, FX_LPBYTE dest_data, int pitch, FX_B
OOL bTranslateColor, FX_LPBYTE offsets) | 782 FX_BOOL CCodec_JpxModule::Decode(void* ctx, FX_LPBYTE dest_data, int pitch, FX_B
OOL bTranslateColor, FX_LPBYTE offsets) |
| 793 { | 783 { |
| 794 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; | 784 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; |
| 795 return pDecoder->Decode(dest_data, pitch, bTranslateColor, offsets); | 785 return pDecoder->Decode(dest_data, pitch, bTranslateColor, offsets); |
| 796 } | 786 } |
| 797 void CCodec_JpxModule::DestroyDecoder(void* ctx) | 787 void CCodec_JpxModule::DestroyDecoder(void* ctx) |
| 798 { | 788 { |
| 799 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; | 789 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx; |
| 800 delete pDecoder; | 790 delete pDecoder; |
| 801 } | 791 } |
| OLD | NEW |