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 |