| 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 "core/fxcodec/include/fx_codec.h" | 7 #include "core/fxcodec/include/fx_codec.h" |
| 8 #include "core/fxge/include/fx_dib.h" | 8 #include "core/fxge/include/fx_dib.h" |
| 9 #include "core/fxge/include/fx_ge.h" | 9 #include "core/fxge/include/fx_ge.h" |
| 10 | 10 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 } | 41 } |
| 42 if (l < r) { | 42 if (l < r) { |
| 43 alut[r] = alut[l]; | 43 alut[r] = alut[l]; |
| 44 clut[r--] = clut[l]; | 44 clut[r--] = clut[l]; |
| 45 } | 45 } |
| 46 } | 46 } |
| 47 alut[l] = p_a; | 47 alut[l] = p_a; |
| 48 clut[l] = p_c; | 48 clut[l] = p_c; |
| 49 return l; | 49 return l; |
| 50 } | 50 } |
| 51 |
| 51 void _Qsort(uint32_t* alut, uint32_t* clut, int l, int r) { | 52 void _Qsort(uint32_t* alut, uint32_t* clut, int l, int r) { |
| 52 if (l < r) { | 53 if (l < r) { |
| 53 int pI = _Partition(alut, clut, l, r); | 54 int pI = _Partition(alut, clut, l, r); |
| 54 _Qsort(alut, clut, l, pI - 1); | 55 _Qsort(alut, clut, l, pI - 1); |
| 55 _Qsort(alut, clut, pI + 1, r); | 56 _Qsort(alut, clut, pI + 1, r); |
| 56 } | 57 } |
| 57 } | 58 } |
| 59 |
| 58 void _ColorDecode(uint32_t pal_v, uint8_t& r, uint8_t& g, uint8_t& b) { | 60 void _ColorDecode(uint32_t pal_v, uint8_t& r, uint8_t& g, uint8_t& b) { |
| 59 r = (uint8_t)((pal_v & 0xf00) >> 4); | 61 r = (uint8_t)((pal_v & 0xf00) >> 4); |
| 60 g = (uint8_t)(pal_v & 0x0f0); | 62 g = (uint8_t)(pal_v & 0x0f0); |
| 61 b = (uint8_t)((pal_v & 0x00f) << 4); | 63 b = (uint8_t)((pal_v & 0x00f) << 4); |
| 62 } | 64 } |
| 65 |
| 63 void _Obtain_Pal(uint32_t* aLut, | 66 void _Obtain_Pal(uint32_t* aLut, |
| 64 uint32_t* cLut, | 67 uint32_t* cLut, |
| 65 uint32_t* dest_pal, | 68 uint32_t* dest_pal, |
| 66 uint32_t lut) { | 69 uint32_t lut) { |
| 67 uint32_t lut_1 = lut - 1; | 70 uint32_t lut_1 = lut - 1; |
| 68 for (int row = 0; row < 256; row++) { | 71 for (int row = 0; row < 256; row++) { |
| 69 int lut_offset = lut_1 - row; | 72 int lut_offset = lut_1 - row; |
| 70 if (lut_offset < 0) { | 73 if (lut_offset < 0) { |
| 71 lut_offset += 256; | 74 lut_offset += 256; |
| 72 } | 75 } |
| 73 uint32_t color = cLut[lut_offset]; | 76 uint32_t color = cLut[lut_offset]; |
| 74 uint8_t r; | 77 uint8_t r; |
| 75 uint8_t g; | 78 uint8_t g; |
| 76 uint8_t b; | 79 uint8_t b; |
| 77 _ColorDecode(color, r, g, b); | 80 _ColorDecode(color, r, g, b); |
| 78 dest_pal[row] = ((uint32_t)r << 16) | ((uint32_t)g << 8) | b | 0xff000000; | 81 dest_pal[row] = ((uint32_t)r << 16) | ((uint32_t)g << 8) | b | 0xff000000; |
| 79 aLut[lut_offset] = row; | 82 aLut[lut_offset] = row; |
| 80 } | 83 } |
| 81 } | 84 } |
| 82 | 85 |
| 83 CFX_Palette::CFX_Palette() { | 86 CFX_Palette::CFX_Palette() { |
| 84 m_pPalette = nullptr; | 87 m_pPalette = nullptr; |
| 85 m_cLut = nullptr; | 88 m_cLut = nullptr; |
| 86 m_aLut = nullptr; | 89 m_aLut = nullptr; |
| 87 m_lut = 0; | 90 m_lut = 0; |
| 88 } | 91 } |
| 92 |
| 89 CFX_Palette::~CFX_Palette() { | 93 CFX_Palette::~CFX_Palette() { |
| 90 FX_Free(m_pPalette); | 94 FX_Free(m_pPalette); |
| 91 FX_Free(m_cLut); | 95 FX_Free(m_cLut); |
| 92 FX_Free(m_aLut); | 96 FX_Free(m_aLut); |
| 93 m_lut = 0; | 97 m_lut = 0; |
| 94 } | 98 } |
| 99 |
| 95 FX_BOOL CFX_Palette::BuildPalette(const CFX_DIBSource* pBitmap) { | 100 FX_BOOL CFX_Palette::BuildPalette(const CFX_DIBSource* pBitmap) { |
| 96 if (!pBitmap) { | 101 if (!pBitmap) { |
| 97 return FALSE; | 102 return FALSE; |
| 98 } | 103 } |
| 99 FX_Free(m_pPalette); | 104 FX_Free(m_pPalette); |
| 100 m_pPalette = FX_Alloc(uint32_t, 256); | 105 m_pPalette = FX_Alloc(uint32_t, 256); |
| 101 int bpp = pBitmap->GetBPP() / 8; | 106 int bpp = pBitmap->GetBPP() / 8; |
| 102 int width = pBitmap->GetWidth(); | 107 int width = pBitmap->GetWidth(); |
| 103 int height = pBitmap->GetHeight(); | 108 int height = pBitmap->GetHeight(); |
| 104 FX_Free(m_cLut); | 109 FX_Free(m_cLut); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 124 if (m_aLut[row] != 0) { | 129 if (m_aLut[row] != 0) { |
| 125 m_aLut[m_lut] = m_aLut[row]; | 130 m_aLut[m_lut] = m_aLut[row]; |
| 126 m_cLut[m_lut] = row; | 131 m_cLut[m_lut] = row; |
| 127 m_lut++; | 132 m_lut++; |
| 128 } | 133 } |
| 129 } | 134 } |
| 130 _Qsort(m_aLut, m_cLut, 0, m_lut - 1); | 135 _Qsort(m_aLut, m_cLut, 0, m_lut - 1); |
| 131 _Obtain_Pal(m_aLut, m_cLut, m_pPalette, m_lut); | 136 _Obtain_Pal(m_aLut, m_cLut, m_pPalette, m_lut); |
| 132 return TRUE; | 137 return TRUE; |
| 133 } | 138 } |
| 139 |
| 134 FX_BOOL ConvertBuffer_1bppMask2Gray(uint8_t* dest_buf, | 140 FX_BOOL ConvertBuffer_1bppMask2Gray(uint8_t* dest_buf, |
| 135 int dest_pitch, | 141 int dest_pitch, |
| 136 int width, | 142 int width, |
| 137 int height, | 143 int height, |
| 138 const CFX_DIBSource* pSrcBitmap, | 144 const CFX_DIBSource* pSrcBitmap, |
| 139 int src_left, | 145 int src_left, |
| 140 int src_top) { | 146 int src_top) { |
| 141 uint8_t set_gray, reset_gray; | 147 uint8_t set_gray, reset_gray; |
| 142 set_gray = 0xff; | 148 set_gray = 0xff; |
| 143 reset_gray = 0x00; | 149 reset_gray = 0x00; |
| 144 for (int row = 0; row < height; row++) { | 150 for (int row = 0; row < height; row++) { |
| 145 uint8_t* dest_scan = dest_buf + row * dest_pitch; | 151 uint8_t* dest_scan = dest_buf + row * dest_pitch; |
| 146 FXSYS_memset(dest_scan, reset_gray, width); | 152 FXSYS_memset(dest_scan, reset_gray, width); |
| 147 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); | 153 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); |
| 148 for (int col = src_left; col < src_left + width; col++) { | 154 for (int col = src_left; col < src_left + width; col++) { |
| 149 if (src_scan[col / 8] & (1 << (7 - col % 8))) { | 155 if (src_scan[col / 8] & (1 << (7 - col % 8))) { |
| 150 *dest_scan = set_gray; | 156 *dest_scan = set_gray; |
| 151 } | 157 } |
| 152 dest_scan++; | 158 dest_scan++; |
| 153 } | 159 } |
| 154 } | 160 } |
| 155 return TRUE; | 161 return TRUE; |
| 156 } | 162 } |
| 163 |
| 157 FX_BOOL ConvertBuffer_8bppMask2Gray(uint8_t* dest_buf, | 164 FX_BOOL ConvertBuffer_8bppMask2Gray(uint8_t* dest_buf, |
| 158 int dest_pitch, | 165 int dest_pitch, |
| 159 int width, | 166 int width, |
| 160 int height, | 167 int height, |
| 161 const CFX_DIBSource* pSrcBitmap, | 168 const CFX_DIBSource* pSrcBitmap, |
| 162 int src_left, | 169 int src_left, |
| 163 int src_top) { | 170 int src_top) { |
| 164 for (int row = 0; row < height; row++) { | 171 for (int row = 0; row < height; row++) { |
| 165 uint8_t* dest_scan = dest_buf + row * dest_pitch; | 172 uint8_t* dest_scan = dest_buf + row * dest_pitch; |
| 166 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; | 173 const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; |
| 167 FXSYS_memcpy(dest_scan, src_scan, width); | 174 FXSYS_memcpy(dest_scan, src_scan, width); |
| 168 } | 175 } |
| 169 return TRUE; | 176 return TRUE; |
| 170 } | 177 } |
| 178 |
| 171 FX_BOOL ConvertBuffer_1bppPlt2Gray(uint8_t* dest_buf, | 179 FX_BOOL ConvertBuffer_1bppPlt2Gray(uint8_t* dest_buf, |
| 172 int dest_pitch, | 180 int dest_pitch, |
| 173 int width, | 181 int width, |
| 174 int height, | 182 int height, |
| 175 const CFX_DIBSource* pSrcBitmap, | 183 const CFX_DIBSource* pSrcBitmap, |
| 176 int src_left, | 184 int src_left, |
| 177 int src_top) { | 185 int src_top) { |
| 178 uint32_t* src_plt = pSrcBitmap->GetPalette(); | 186 uint32_t* src_plt = pSrcBitmap->GetPalette(); |
| 179 uint8_t gray[2]; | 187 uint8_t gray[2]; |
| 180 uint8_t reset_r; | 188 uint8_t reset_r; |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 } | 650 } |
| 643 | 651 |
| 644 FX_BOOL ConvertBuffer(FXDIB_Format dest_format, | 652 FX_BOOL ConvertBuffer(FXDIB_Format dest_format, |
| 645 uint8_t* dest_buf, | 653 uint8_t* dest_buf, |
| 646 int dest_pitch, | 654 int dest_pitch, |
| 647 int width, | 655 int width, |
| 648 int height, | 656 int height, |
| 649 const CFX_DIBSource* pSrcBitmap, | 657 const CFX_DIBSource* pSrcBitmap, |
| 650 int src_left, | 658 int src_left, |
| 651 int src_top, | 659 int src_top, |
| 652 uint32_t*& d_pal) { | 660 std::unique_ptr<uint32_t, FxFreeDeleter>* p_pal) { |
| 653 FXDIB_Format src_format = pSrcBitmap->GetFormat(); | 661 FXDIB_Format src_format = pSrcBitmap->GetFormat(); |
| 654 switch (dest_format) { | 662 switch (dest_format) { |
| 655 case FXDIB_Invalid: | 663 case FXDIB_Invalid: |
| 656 case FXDIB_1bppCmyk: | 664 case FXDIB_1bppCmyk: |
| 657 case FXDIB_1bppMask: | 665 case FXDIB_1bppMask: |
| 658 case FXDIB_1bppRgb: | 666 case FXDIB_1bppRgb: |
| 659 ASSERT(FALSE); | 667 ASSERT(FALSE); |
| 660 return FALSE; | 668 return FALSE; |
| 661 case FXDIB_8bppMask: { | 669 case FXDIB_8bppMask: { |
| 662 if ((src_format & 0xff) == 1) { | 670 if ((src_format & 0xff) == 1) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 678 if ((src_format & 0xff) >= 24) { | 686 if ((src_format & 0xff) >= 24) { |
| 679 return ConvertBuffer_RgbOrCmyk2Gray(dest_buf, dest_pitch, width, height, | 687 return ConvertBuffer_RgbOrCmyk2Gray(dest_buf, dest_pitch, width, height, |
| 680 pSrcBitmap, src_left, src_top); | 688 pSrcBitmap, src_left, src_top); |
| 681 } | 689 } |
| 682 return FALSE; | 690 return FALSE; |
| 683 } | 691 } |
| 684 case FXDIB_8bppRgb: | 692 case FXDIB_8bppRgb: |
| 685 case FXDIB_8bppRgba: { | 693 case FXDIB_8bppRgba: { |
| 686 if ((src_format & 0xff) == 8 && !pSrcBitmap->GetPalette()) { | 694 if ((src_format & 0xff) == 8 && !pSrcBitmap->GetPalette()) { |
| 687 return ConvertBuffer(FXDIB_8bppMask, dest_buf, dest_pitch, width, | 695 return ConvertBuffer(FXDIB_8bppMask, dest_buf, dest_pitch, width, |
| 688 height, pSrcBitmap, src_left, src_top, d_pal); | 696 height, pSrcBitmap, src_left, src_top, p_pal); |
| 689 } | 697 } |
| 690 d_pal = FX_Alloc(uint32_t, 256); | 698 p_pal->reset(FX_Alloc(uint32_t, 256)); |
| 691 if (((src_format & 0xff) == 1 || (src_format & 0xff) == 8) && | 699 if (((src_format & 0xff) == 1 || (src_format & 0xff) == 8) && |
| 692 pSrcBitmap->GetPalette()) { | 700 pSrcBitmap->GetPalette()) { |
| 693 return ConvertBuffer_Plt2PltRgb8(dest_buf, dest_pitch, width, height, | 701 return ConvertBuffer_Plt2PltRgb8(dest_buf, dest_pitch, width, height, |
| 694 pSrcBitmap, src_left, src_top, d_pal); | 702 pSrcBitmap, src_left, src_top, |
| 703 p_pal->get()); |
| 695 } | 704 } |
| 696 if ((src_format & 0xff) >= 24) { | 705 if ((src_format & 0xff) >= 24) { |
| 697 return ConvertBuffer_Rgb2PltRgb8(dest_buf, dest_pitch, width, height, | 706 return ConvertBuffer_Rgb2PltRgb8(dest_buf, dest_pitch, width, height, |
| 698 pSrcBitmap, src_left, src_top, d_pal); | 707 pSrcBitmap, src_left, src_top, |
| 708 p_pal->get()); |
| 699 } | 709 } |
| 700 return FALSE; | 710 return FALSE; |
| 701 } | 711 } |
| 702 case FXDIB_Rgb: | 712 case FXDIB_Rgb: |
| 703 case FXDIB_Rgba: { | 713 case FXDIB_Rgba: { |
| 704 if ((src_format & 0xff) == 1) { | 714 if ((src_format & 0xff) == 1) { |
| 705 if (pSrcBitmap->GetPalette()) { | 715 if (pSrcBitmap->GetPalette()) { |
| 706 return ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, | 716 return ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, |
| 707 width, height, pSrcBitmap, src_left, | 717 width, height, pSrcBitmap, src_left, |
| 708 src_top); | 718 src_top); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 ret = pClone->CopyAlphaMask(pSrcAlpha); | 803 ret = pClone->CopyAlphaMask(pSrcAlpha); |
| 794 } | 804 } |
| 795 } | 805 } |
| 796 if (pSrcAlpha && pSrcAlpha != m_pAlphaMask) { | 806 if (pSrcAlpha && pSrcAlpha != m_pAlphaMask) { |
| 797 delete pSrcAlpha; | 807 delete pSrcAlpha; |
| 798 pSrcAlpha = nullptr; | 808 pSrcAlpha = nullptr; |
| 799 } | 809 } |
| 800 if (!ret) | 810 if (!ret) |
| 801 return nullptr; | 811 return nullptr; |
| 802 | 812 |
| 803 uint32_t* pal_8bpp = nullptr; | 813 std::unique_ptr<uint32_t, FxFreeDeleter> pal_8bpp; |
| 804 if (!ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(), | 814 if (!ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(), |
| 805 m_Width, m_Height, this, 0, 0, pal_8bpp)) { | 815 m_Width, m_Height, this, 0, 0, &pal_8bpp)) { |
| 806 FX_Free(pal_8bpp); | |
| 807 return nullptr; | 816 return nullptr; |
| 808 } | 817 } |
| 809 if (pal_8bpp) { | 818 if (pal_8bpp) |
| 810 pClone->CopyPalette(pal_8bpp); | 819 pClone->CopyPalette(pal_8bpp.get()); |
| 811 FX_Free(pal_8bpp); | |
| 812 } | |
| 813 return pClone.release(); | 820 return pClone.release(); |
| 814 } | 821 } |
| 815 | 822 |
| 816 FX_BOOL CFX_DIBitmap::ConvertFormat(FXDIB_Format dest_format) { | 823 FX_BOOL CFX_DIBitmap::ConvertFormat(FXDIB_Format dest_format) { |
| 817 FXDIB_Format src_format = GetFormat(); | 824 FXDIB_Format src_format = GetFormat(); |
| 818 if (dest_format == src_format) | 825 if (dest_format == src_format) |
| 819 return TRUE; | 826 return TRUE; |
| 820 | 827 |
| 821 if (dest_format == FXDIB_8bppMask && src_format == FXDIB_8bppRgb && | 828 if (dest_format == FXDIB_8bppMask && src_format == FXDIB_8bppRgb && |
| 822 !m_pPalette) { | 829 !m_pPalette) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 return FALSE; | 874 return FALSE; |
| 868 } | 875 } |
| 869 pAlphaMask = m_pAlphaMask; | 876 pAlphaMask = m_pAlphaMask; |
| 870 m_pAlphaMask = nullptr; | 877 m_pAlphaMask = nullptr; |
| 871 } else { | 878 } else { |
| 872 pAlphaMask = m_pAlphaMask; | 879 pAlphaMask = m_pAlphaMask; |
| 873 } | 880 } |
| 874 } | 881 } |
| 875 } | 882 } |
| 876 FX_BOOL ret = FALSE; | 883 FX_BOOL ret = FALSE; |
| 877 uint32_t* pal_8bpp = nullptr; | 884 std::unique_ptr<uint32_t, FxFreeDeleter> pal_8bpp; |
| 878 ret = ConvertBuffer(dest_format, dest_buf, dest_pitch, m_Width, m_Height, | 885 ret = ConvertBuffer(dest_format, dest_buf, dest_pitch, m_Width, m_Height, |
| 879 this, 0, 0, pal_8bpp); | 886 this, 0, 0, &pal_8bpp); |
| 880 if (!ret) { | 887 if (!ret) { |
| 881 FX_Free(pal_8bpp); | 888 if (pAlphaMask != m_pAlphaMask) |
| 882 if (pAlphaMask != m_pAlphaMask) { | |
| 883 delete pAlphaMask; | 889 delete pAlphaMask; |
| 884 } | |
| 885 FX_Free(dest_buf); | 890 FX_Free(dest_buf); |
| 886 return FALSE; | 891 return FALSE; |
| 887 } | 892 } |
| 888 if (m_pAlphaMask && pAlphaMask != m_pAlphaMask) { | 893 if (m_pAlphaMask && pAlphaMask != m_pAlphaMask) |
| 889 delete m_pAlphaMask; | 894 delete m_pAlphaMask; |
| 890 } | |
| 891 m_pAlphaMask = pAlphaMask; | 895 m_pAlphaMask = pAlphaMask; |
| 892 FX_Free(m_pPalette); | 896 m_pPalette = std::move(pal_8bpp); |
| 893 m_pPalette = pal_8bpp; | 897 if (!m_bExtBuf) |
| 894 if (!m_bExtBuf) { | |
| 895 FX_Free(m_pBuffer); | 898 FX_Free(m_pBuffer); |
| 896 } | |
| 897 m_bExtBuf = FALSE; | 899 m_bExtBuf = FALSE; |
| 898 m_pBuffer = dest_buf; | 900 m_pBuffer = dest_buf; |
| 899 m_bpp = (uint8_t)dest_format; | 901 m_bpp = (uint8_t)dest_format; |
| 900 m_AlphaFlag = (uint8_t)(dest_format >> 8); | 902 m_AlphaFlag = (uint8_t)(dest_format >> 8); |
| 901 m_Pitch = dest_pitch; | 903 m_Pitch = dest_pitch; |
| 902 return TRUE; | 904 return TRUE; |
| 903 } | 905 } |
| OLD | NEW |