Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: core/fpdfapi/fpdf_edit/fpdf_edit_image.cpp

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

Powered by Google App Engine
This is Rietveld 408576698