1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved. 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file. 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_module.h" 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_page.h" 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxcodec/fx_codec.h" 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_render.h" 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../fpdf_page/pageint.h" 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../fpdf_render/render_int.h" 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Dictionary* CPDF_Image::InitJPEG(FX_LPBYTE pData, FX_DWORD size) 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 width, height, color_trans, num_comps, bits; 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!CPDF_ModuleMgr::Get()->GetJpegModule()-> 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LoadInfo(pData, size, width, height, num_comps, bits, color_trans)) { 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary; 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtName("Type", "XObject"); 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtName("Subtype", "Image"); 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtInteger("Width", width); 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtInteger("Height", height); 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPCSTR csname = NULL; 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (num_comps == 1) { 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov csname = "DeviceGray"; 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (num_comps == 3) { 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov csname = "DeviceRGB"; 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (num_comps == 4) { 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov csname = "DeviceCMYK"; 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Array* pDecode = CPDF_Array::Create(); 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int n = 0; n < 4; n ++) { 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDecode->AddInteger(1); 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDecode->AddInteger(0); 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAt(FX_BSTRC("Decode"), pDecode); 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtName("ColorSpace", csname); 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtInteger("BitsPerComponent", bits); 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtName("Filter", "DCTDecode"); 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!color_trans) { 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Dictionary* pParms = FX_NEW CPDF_Dictionary; 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAt("DecodeParms", pParms); 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pParms->SetAtInteger("ColorTransform", 0); 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_bIsMask = FALSE; 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_Width = width; 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_Height = height; 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (m_pStream == NULL) { 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pStream = FX_NEW CPDF_Stream(NULL, 0, NULL); 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pDict; 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Image::SetJpegImage(FX_LPBYTE pData, FX_DWORD size) 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Dictionary *pDict = InitJPEG(pData, size); 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!pDict) { 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pStream->InitStream(pData, size, pDict); 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Image::SetJpegImage(IFX_FileRead *pFile) 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD size = (FX_DWORD)pFile->GetSize(); 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!size) { 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD dwEstimateSize = size; 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwEstimateSize > 8192) { 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dwEstimateSize = 8192; 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE pData = FX_Alloc(FX_BYTE, dwEstimateSize); 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!pData) { 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFile->ReadBlock(pData, 0, dwEstimateSize); 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Dictionary *pDict = InitJPEG(pData, dwEstimateSize); 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(pData); 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!pDict && size > dwEstimateSize) { 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pData = FX_Alloc(FX_BYTE, size); 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!pData) { 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFile->ReadBlock(pData, 0, size); 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict = InitJPEG(pData, size); 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(pData); 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!pDict) { 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pStream->InitStream(pFile, pDict); 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _DCTEncodeBitmap(CPDF_Dictionary *pBitmapDict, const CFX_DIBitmap* pBitmap, int quality, FX_LPBYTE &buf, FX_STRSIZE &size) 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _JBIG2EncodeBitmap(CPDF_Dictionary *pBitmapDict, const CFX_DIBitmap *pBitmap, CPDF_Document *pDoc, FX_LPBYTE &buf, FX_STRSIZE &size, FX_BOOL bLossLess) 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, FX_INT32 iCompress, IFX_FileWrite *pFileWrite, IFX_FileRead *pFileRead, const CFX_DIBitmap* pMask, const CPDF_ImageSetParam* pParam) 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 BitmapWidth = pBitmap->GetWidth(); 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 BitmapHeight = pBitmap->GetHeight(); 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (BitmapWidth < 1 || BitmapHeight < 1) { 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE src_buf = pBitmap->GetBuffer(); 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 src_pitch = pBitmap->GetPitch(); 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 bpp = pBitmap->GetBPP(); 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_BOOL bUseMatte = pParam && pParam->pMatteColor && (pBitmap->GetFormat() == FXDIB_Argb); 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary; 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("XObject")); 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image")); 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtInteger(FX_BSTRC("Width"), BitmapWidth); 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtInteger(FX_BSTRC("Height"), BitmapHeight); 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE dest_buf = NULL; 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bpp == 1) { 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0; 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 set_a = 0, set_r = 0, set_g = 0, set_b = 0; 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!pBitmap->IsAlphaMask()) { 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ArgbDecode(pBitmap->GetPaletteArgb(0), reset_a, reset_r, reset_g, reset_b); 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b); 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (set_a == 0 || reset_a == 0) { 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAt(FX_BSTRC("ImageMask"), FX_NEW CPDF_Boolean(TRUE)); 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (reset_a == 0) { 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Array* pArray = FX_NEW CPDF_Array; 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pArray->AddInteger(1); 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pArray->AddInteger(0); 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAt(FX_BSTRC("Decode"), pArray); 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Array* pCS = FX_NEW CPDF_Array; 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCS->AddName(FX_BSTRC("Indexed")); 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCS->AddName(FX_BSTRC("DeviceRGB")); 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCS->AddInteger(1); 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_ByteString ct; 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPSTR pBuf = ct.GetBuffer(6); 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pBuf[0] = (FX_CHAR)reset_r; 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pBuf[1] = (FX_CHAR)reset_g; 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pBuf[2] = (FX_CHAR)reset_b; 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pBuf[3] = (FX_CHAR)set_r; 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pBuf[4] = (FX_CHAR)set_g; 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pBuf[5] = (FX_CHAR)set_b; 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ct.ReleaseBuffer(6); 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCS->Add(CPDF_String::Create(ct, TRUE)); 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAt(FX_BSTRC("ColorSpace"), pCS); 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtInteger(FX_BSTRC("BitsPerComponent"), 1); 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_pitch = (BitmapWidth + 7) / 8; 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov opType = 1; 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov opType = 0; 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (bpp == 8) { 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 iPalette = pBitmap->GetPaletteSize(); 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (iPalette > 0) { 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Array* pCS = FX_NEW CPDF_Array; 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pDocument->AddIndirectObject(pCS); 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCS->AddName(FX_BSTRC("Indexed")); 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCS->AddName(FX_BSTRC("DeviceRGB")); 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCS->AddInteger(iPalette - 1); 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE pColorTable = FX_Alloc(FX_BYTE, iPalette * 3); 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE ptr = pColorTable; 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (FX_INT32 i = 0; i < iPalette; i ++) { 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD argb = pBitmap->GetPaletteArgb(i); 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ptr[0] = (FX_BYTE)(argb >> 16); 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ptr[1] = (FX_BYTE)(argb >> 8); 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ptr[2] = (FX_BYTE)argb; 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ptr += 3; 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Stream *pCTS = CPDF_Stream::Create(pColorTable, iPalette * 3, CPDF_Dictionary::Create()); 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pDocument->AddIndirectObject(pCTS); 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCS->AddReference(m_pDocument, pCTS); 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtReference(FX_BSTRC("ColorSpace"), m_pDocument, pCS); 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtName(FX_BSTRC("ColorSpace"), FX_BSTRC("DeviceGray")); 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtInteger(FX_BSTRC("BitsPerComponent"), 8); 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_pitch = BitmapWidth; 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov opType = 1; 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov opType = 0; 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtName(FX_BSTRC("ColorSpace"), FX_BSTRC("DeviceRGB")); 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtInteger(FX_BSTRC("BitsPerComponent"), 8); 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_pitch = BitmapWidth * 3; 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov opType = 2; 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov opType = 0; 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_DIBitmap* pMaskBitmap = NULL; 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pBitmap->HasAlpha()) { 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskBitmap = pBitmap->GetAlphaMask(); 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!pMaskBitmap && pMask) { 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXDIB_Format maskFormat = pMask->GetFormat(); 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (maskFormat == FXDIB_1bppMask || maskFormat == FXDIB_8bppMask) { 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskBitmap = pMask; 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pMaskBitmap) { 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 maskWidth = pMaskBitmap->GetWidth(); 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 maskHeight = pMaskBitmap->GetHeight(); 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE mask_buf = NULL; 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_STRSIZE mask_size; 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_BOOL bDeleteMask = TRUE; 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Dictionary* pMaskDict = FX_NEW CPDF_Dictionary; 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("XObject")); 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image")); 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskDict->SetAtInteger(FX_BSTRC("Width"), maskWidth); 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskDict->SetAtInteger(FX_BSTRC("Height"), maskHeight); 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskDict->SetAtName(FX_BSTRC("ColorSpace"), FX_BSTRC("DeviceGray")); 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskDict->SetAtInteger(FX_BSTRC("BitsPerComponent"), 8); 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pMaskBitmap->GetBPP() == 8 && (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) { 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _DCTEncodeBitmap(pMaskDict, pMaskBitmap, pParam ? pParam->nQuality : 75, mask_buf, mask_size); 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) { 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _JBIG2EncodeBitmap(pMaskDict, pMaskBitmap, m_pDocument, mask_buf, mask_size, TRUE); 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mask_size = maskHeight * maskWidth; 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mask_buf = FX_Alloc(FX_BYTE, mask_size); 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (FX_INT32 a = 0; a < maskHeight; a ++) { 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXSYS_memcpy32(mask_buf + a * maskWidth, pMaskBitmap->GetScanline(a), maskWidth); 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pMaskDict) { 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskDict->SetAtInteger(FX_BSTRC("Length"), mask_size); 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Stream* pMaskStream = NULL; 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bUseMatte) { 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int a, r, g, b; 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ArgbDecode(*(pParam->pMatteColor), a, r, g, b); 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Array* pMatte = FX_NEW CPDF_Array; 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMatte->AddInteger(r); 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMatte->AddInteger(g); 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMatte->AddInteger(b); 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskDict->SetAt(FX_BSTRC("Matte"), pMatte); 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pMaskStream = FX_NEW CPDF_Stream(mask_buf, mask_size, pMaskDict); 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pDocument->AddIndirectObject(pMaskStream); 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bDeleteMask = FALSE; 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->SetAtReference(FX_BSTRC("SMask"), m_pDocument, pMaskStream); 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pBitmap->HasAlpha()) { 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete pMaskBitmap; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_BOOL bStream = pFileWrite != NULL && pFileRead != NULL; 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (opType == 0) { 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) { 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pBitmap->GetBPP() == 1) { 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _JBIG2EncodeBitmap(pDict, pBitmap, m_pDocument, dest_buf, dest_size, TRUE); 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pBitmap->GetBPP() == 1) { 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _JBIG2EncodeBitmap(pDict, pBitmap, m_pDocument, dest_buf, dest_size, FALSE); 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette() != NULL) { 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_DIBitmap *pNewBitmap = FX_NEW CFX_DIBitmap(); 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pNewBitmap->Copy(pBitmap); 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pNewBitmap->ConvertFormat(FXDIB_Rgb); 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SetImage(pNewBitmap, iCompress, pFileWrite, pFileRead); 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pDict) { 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict->Release(); 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDict = NULL; 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dest_buf) { 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(dest_buf); 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_buf = NULL; 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_size = 0; 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete pNewBitmap; 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bUseMatte) { 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_DIBitmap *pNewBitmap = FX_NEW CFX_DIBitmap(); 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pNewBitmap->Create(BitmapWidth, BitmapHeight, FXDIB_Argb); 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE dst_buf = pNewBitmap->GetBuffer(); 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 src_offset = 0; 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (FX_INT32 row = 0; row < BitmapHeight; row ++) { 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov src_offset = row * src_pitch; 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (FX_INT32 column = 0; column < BitmapWidth; column ++) { 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT alpha = src_buf[src_offset + 3] / 255.0f; 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dst_buf[src_offset] = (FX_BYTE)(src_buf[src_offset] * alpha); 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dst_buf[src_offset + 1] = (FX_BYTE)(src_buf[src_offset + 1] * alpha); 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dst_buf[src_offset + 2] = (FX_BYTE)(src_buf[src_offset + 2] * alpha); 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dst_buf[src_offset + 3] = (FX_BYTE)(src_buf[src_offset + 3]); 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov src_offset += 4; 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _DCTEncodeBitmap(pDict, pNewBitmap, pParam ? pParam->nQuality : 75, dest_buf, dest_size); 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete pNewBitmap; 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _DCTEncodeBitmap(pDict, pBitmap, pParam ? pParam->nQuality : 75, dest_buf, dest_size); 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bStream) { 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFileWrite->WriteBlock(dest_buf, dest_size); 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(dest_buf); 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_buf = NULL; 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (opType == 1) { 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!bStream) { 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_size = dest_pitch * BitmapHeight; 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_buf = FX_Alloc(FX_BYTE, dest_size); 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE pDest = dest_buf; 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (FX_INT32 i = 0; i < BitmapHeight; i ++) { 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!bStream) { 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXSYS_memcpy32(pDest, src_buf, dest_pitch); 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDest += dest_pitch; 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFileWrite->WriteBlock(src_buf, dest_pitch); 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov src_buf += src_pitch; 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (opType == 2) { 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!bStream) { 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_size = dest_pitch * BitmapHeight; 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_buf = FX_Alloc(FX_BYTE, dest_size); 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_buf = FX_Alloc(FX_BYTE, dest_pitch); 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE pDest = dest_buf; 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 src_offset = 0; 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_INT32 dest_offset = 0; 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (FX_INT32 row = 0; row < BitmapHeight; row ++) { 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov src_offset = row * src_pitch; 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (FX_INT32 column = 0; column < BitmapWidth; column ++) { 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT alpha = bUseMatte ? src_buf[src_offset + 3] / 255.0f : 1; 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDest[dest_offset] = (FX_BYTE)(src_buf[src_offset + 2] * alpha); 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDest[dest_offset + 1] = (FX_BYTE)(src_buf[src_offset + 1] * alpha); 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDest[dest_offset + 2] = (FX_BYTE)(src_buf[src_offset] * alpha); 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_offset += 3; 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov src_offset += bpp == 24 ? 3 : 4; 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bStream) { 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFileWrite->WriteBlock(pDest, dest_pitch); 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDest = dest_buf; 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDest += dest_pitch; 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_offset = 0; 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bStream) { 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(dest_buf); 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dest_buf = NULL; 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (m_pStream == NULL) { 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pStream = FX_NEW CPDF_Stream(NULL, 0, NULL); 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!bStream) { 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pStream->InitStream(dest_buf, dest_size, pDict); 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFileWrite->Flush(); 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pStream->InitStream(pFileRead, pDict); 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_bIsMask = pBitmap->IsAlphaMask(); 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_Width = BitmapWidth; 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_Height = BitmapHeight; 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dest_buf) { 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(dest_buf); 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap); 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 375