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/src/fxcodec/codec/fx_codec_jpeg.cpp

Issue 1540993004: Revert "Cleanup: Remove unused CFX_PSRenderer and various encoders it used." (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: Created 4 years, 12 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
« no previous file with comments | « core/src/fxcodec/codec/fx_codec_flate.cpp ('k') | core/src/fxge/ge/fx_ge_ps.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <setjmp.h> 7 #include <setjmp.h>
8 8
9 #include "codec_int.h" 9 #include "codec_int.h"
10 #include "core/include/fxcodec/fx_codec.h" 10 #include "core/include/fxcodec/fx_codec.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 }; 67 };
68 extern "C" { 68 extern "C" {
69 static void _error_do_nothing(j_common_ptr cinfo) {} 69 static void _error_do_nothing(j_common_ptr cinfo) {}
70 }; 70 };
71 extern "C" { 71 extern "C" {
72 static void _error_do_nothing1(j_common_ptr cinfo, int) {} 72 static void _error_do_nothing1(j_common_ptr cinfo, int) {}
73 }; 73 };
74 extern "C" { 74 extern "C" {
75 static void _error_do_nothing2(j_common_ptr cinfo, char*) {} 75 static void _error_do_nothing2(j_common_ptr cinfo, char*) {}
76 }; 76 };
77 #define JPEG_MARKER_EXIF (JPEG_APP0 + 1)
78 #define JPEG_MARKER_ICC (JPEG_APP0 + 2)
79 #define JPEG_MARKER_AUTHORTIME (JPEG_APP0 + 3)
80 #define JPEG_MARKER_MAXSIZE 0xFFFF
81 #define JPEG_OVERHEAD_LEN 14
82 static FX_BOOL _JpegEmbedIccProfile(j_compress_ptr cinfo,
83 const uint8_t* icc_buf_ptr,
84 FX_DWORD icc_length) {
85 if (!icc_buf_ptr || icc_length == 0) {
86 return FALSE;
87 }
88 FX_DWORD icc_segment_size = (JPEG_MARKER_MAXSIZE - 2 - JPEG_OVERHEAD_LEN);
89 FX_DWORD icc_segment_num = (icc_length / icc_segment_size) + 1;
90 if (icc_segment_num > 255) {
91 return FALSE;
92 }
93 FX_DWORD icc_data_length =
94 JPEG_OVERHEAD_LEN + (icc_segment_num > 1 ? icc_segment_size : icc_length);
95 uint8_t* icc_data = FX_Alloc(uint8_t, icc_data_length);
96 FXSYS_memcpy(icc_data, "\x49\x43\x43\x5f\x50\x52\x4f\x46\x49\x4c\x45\x00",
97 12);
98 icc_data[13] = (uint8_t)icc_segment_num;
99 for (uint8_t i = 0; i < (icc_segment_num - 1); i++) {
100 icc_data[12] = i + 1;
101 FXSYS_memcpy(icc_data + JPEG_OVERHEAD_LEN,
102 icc_buf_ptr + i * icc_segment_size, icc_segment_size);
103 jpeg_write_marker(cinfo, JPEG_MARKER_ICC, icc_data, icc_data_length);
104 }
105 icc_data[12] = (uint8_t)icc_segment_num;
106 FX_DWORD icc_size = (icc_segment_num - 1) * icc_segment_size;
107 FXSYS_memcpy(icc_data + JPEG_OVERHEAD_LEN, icc_buf_ptr + icc_size,
108 icc_length - icc_size);
109 jpeg_write_marker(cinfo, JPEG_MARKER_ICC, icc_data,
110 JPEG_OVERHEAD_LEN + icc_length - icc_size);
111 FX_Free(icc_data);
112 return TRUE;
113 }
114 extern "C" {
115 static void _dest_do_nothing(j_compress_ptr cinfo) {}
116 };
117 extern "C" {
118 static boolean _dest_empty(j_compress_ptr cinfo) {
119 return FALSE;
120 }
121 };
122 #define JPEG_BLOCK_SIZE 1048576
123 static void _JpegEncode(const CFX_DIBSource* pSource,
124 uint8_t*& dest_buf,
125 FX_STRSIZE& dest_size,
126 int quality,
127 const uint8_t* icc_buf,
128 FX_DWORD icc_length) {
129 struct jpeg_error_mgr jerr;
130 jerr.error_exit = _error_do_nothing;
131 jerr.emit_message = _error_do_nothing1;
132 jerr.output_message = _error_do_nothing;
133 jerr.format_message = _error_do_nothing2;
134 jerr.reset_error_mgr = _error_do_nothing;
77 135
78 #define JPEG_MARKER_ICC (JPEG_APP0 + 2) 136 struct jpeg_compress_struct cinfo;
79 #define JPEG_MARKER_MAXSIZE 0xFFFF 137 memset(&cinfo, 0, sizeof(cinfo));
80 138 cinfo.err = &jerr;
81 static bool JpegLoadInfo(const uint8_t* src_buf, 139 jpeg_create_compress(&cinfo);
82 FX_DWORD src_size, 140 int Bpp = pSource->GetBPP() / 8;
83 int* width, 141 FX_DWORD nComponents = Bpp >= 3 ? (pSource->IsCmykImage() ? 4 : 3) : 1;
84 int* height, 142 FX_DWORD pitch = pSource->GetPitch();
85 int* num_components, 143 FX_DWORD width = pdfium::base::checked_cast<FX_DWORD>(pSource->GetWidth());
86 int* bits_per_components, 144 FX_DWORD height = pdfium::base::checked_cast<FX_DWORD>(pSource->GetHeight());
87 bool* color_transform) { 145 FX_SAFE_DWORD safe_buf_len = width;
146 safe_buf_len *= height;
147 safe_buf_len *= nComponents;
148 safe_buf_len += 1024;
149 if (icc_length) {
150 safe_buf_len += 255 * 18;
151 safe_buf_len += icc_length;
152 }
153 FX_DWORD dest_buf_length = 0;
154 if (!safe_buf_len.IsValid()) {
155 dest_buf = nullptr;
156 } else {
157 dest_buf_length = safe_buf_len.ValueOrDie();
158 dest_buf = FX_TryAlloc(uint8_t, dest_buf_length);
159 const int MIN_TRY_BUF_LEN = 1024;
160 while (!dest_buf && dest_buf_length > MIN_TRY_BUF_LEN) {
161 dest_buf_length >>= 1;
162 dest_buf = FX_TryAlloc(uint8_t, dest_buf_length);
163 }
164 }
165 if (!dest_buf) {
166 FX_OutOfMemoryTerminate();
167 }
168 struct jpeg_destination_mgr dest;
169 dest.init_destination = _dest_do_nothing;
170 dest.term_destination = _dest_do_nothing;
171 dest.empty_output_buffer = _dest_empty;
172 dest.next_output_byte = dest_buf;
173 dest.free_in_buffer = dest_buf_length;
174 cinfo.dest = &dest;
175 cinfo.image_width = width;
176 cinfo.image_height = height;
177 cinfo.input_components = nComponents;
178 if (nComponents == 1) {
179 cinfo.in_color_space = JCS_GRAYSCALE;
180 } else if (nComponents == 3) {
181 cinfo.in_color_space = JCS_RGB;
182 } else {
183 cinfo.in_color_space = JCS_CMYK;
184 }
185 uint8_t* line_buf = NULL;
186 if (nComponents > 1) {
187 line_buf = FX_Alloc2D(uint8_t, width, nComponents);
188 }
189 jpeg_set_defaults(&cinfo);
190 if (quality != 75) {
191 jpeg_set_quality(&cinfo, quality, TRUE);
192 }
193 jpeg_start_compress(&cinfo, TRUE);
194 _JpegEmbedIccProfile(&cinfo, icc_buf, icc_length);
195 JSAMPROW row_pointer[1];
196 JDIMENSION row;
197 while (cinfo.next_scanline < cinfo.image_height) {
198 const uint8_t* src_scan = pSource->GetScanline(cinfo.next_scanline);
199 if (nComponents > 1) {
200 uint8_t* dest_scan = line_buf;
201 if (nComponents == 3) {
202 for (FX_DWORD i = 0; i < width; i++) {
203 dest_scan[0] = src_scan[2];
204 dest_scan[1] = src_scan[1];
205 dest_scan[2] = src_scan[0];
206 dest_scan += 3;
207 src_scan += Bpp;
208 }
209 } else {
210 for (FX_DWORD i = 0; i < pitch; i++) {
211 *dest_scan++ = ~*src_scan++;
212 }
213 }
214 row_pointer[0] = line_buf;
215 } else {
216 row_pointer[0] = (uint8_t*)src_scan;
217 }
218 row = cinfo.next_scanline;
219 jpeg_write_scanlines(&cinfo, row_pointer, 1);
220 if (cinfo.next_scanline == row) {
221 dest_buf =
222 FX_Realloc(uint8_t, dest_buf, dest_buf_length + JPEG_BLOCK_SIZE);
223 dest.next_output_byte = dest_buf + dest_buf_length - dest.free_in_buffer;
224 dest_buf_length += JPEG_BLOCK_SIZE;
225 dest.free_in_buffer += JPEG_BLOCK_SIZE;
226 }
227 }
228 jpeg_finish_compress(&cinfo);
229 jpeg_destroy_compress(&cinfo);
230 FX_Free(line_buf);
231 dest_size = dest_buf_length - (FX_STRSIZE)dest.free_in_buffer;
232 }
233 static FX_BOOL _JpegLoadInfo(const uint8_t* src_buf,
234 FX_DWORD src_size,
235 int& width,
236 int& height,
237 int& num_components,
238 int& bits_per_components,
239 FX_BOOL& color_transform,
240 uint8_t** icc_buf_ptr,
241 FX_DWORD* icc_length) {
88 _JpegScanSOI(src_buf, src_size); 242 _JpegScanSOI(src_buf, src_size);
89 struct jpeg_decompress_struct cinfo; 243 struct jpeg_decompress_struct cinfo;
90 struct jpeg_error_mgr jerr; 244 struct jpeg_error_mgr jerr;
91 jerr.error_exit = _error_fatal; 245 jerr.error_exit = _error_fatal;
92 jerr.emit_message = _error_do_nothing1; 246 jerr.emit_message = _error_do_nothing1;
93 jerr.output_message = _error_do_nothing; 247 jerr.output_message = _error_do_nothing;
94 jerr.format_message = _error_do_nothing2; 248 jerr.format_message = _error_do_nothing2;
95 jerr.reset_error_mgr = _error_do_nothing; 249 jerr.reset_error_mgr = _error_do_nothing;
96 jerr.trace_level = 0; 250 jerr.trace_level = 0;
97 cinfo.err = &jerr; 251 cinfo.err = &jerr;
98 jmp_buf mark; 252 jmp_buf mark;
99 cinfo.client_data = &mark; 253 cinfo.client_data = &mark;
100 if (setjmp(mark) == -1) { 254 if (setjmp(mark) == -1) {
101 return false; 255 return FALSE;
102 } 256 }
103 jpeg_create_decompress(&cinfo); 257 jpeg_create_decompress(&cinfo);
104 struct jpeg_source_mgr src; 258 struct jpeg_source_mgr src;
105 src.init_source = _src_do_nothing; 259 src.init_source = _src_do_nothing;
106 src.term_source = _src_do_nothing; 260 src.term_source = _src_do_nothing;
107 src.skip_input_data = _src_skip_data; 261 src.skip_input_data = _src_skip_data;
108 src.fill_input_buffer = _src_fill_buffer; 262 src.fill_input_buffer = _src_fill_buffer;
109 src.resync_to_restart = _src_resync; 263 src.resync_to_restart = _src_resync;
110 src.bytes_in_buffer = src_size; 264 src.bytes_in_buffer = src_size;
111 src.next_input_byte = src_buf; 265 src.next_input_byte = src_buf;
112 cinfo.src = &src; 266 cinfo.src = &src;
113 if (setjmp(mark) == -1) { 267 if (setjmp(mark) == -1) {
114 jpeg_destroy_decompress(&cinfo); 268 jpeg_destroy_decompress(&cinfo);
115 return false; 269 return FALSE;
270 }
271 if (icc_buf_ptr && icc_length) {
272 jpeg_save_markers(&cinfo, JPEG_MARKER_ICC, JPEG_MARKER_MAXSIZE);
116 } 273 }
117 int ret = jpeg_read_header(&cinfo, TRUE); 274 int ret = jpeg_read_header(&cinfo, TRUE);
118 if (ret != JPEG_HEADER_OK) { 275 if (ret != JPEG_HEADER_OK) {
119 jpeg_destroy_decompress(&cinfo); 276 jpeg_destroy_decompress(&cinfo);
120 return false; 277 return FALSE;
121 } 278 }
122 *width = cinfo.image_width; 279 width = cinfo.image_width;
123 *height = cinfo.image_height; 280 height = cinfo.image_height;
124 *num_components = cinfo.num_components; 281 num_components = cinfo.num_components;
125 *color_transform = 282 color_transform =
126 cinfo.jpeg_color_space == JCS_YCbCr || cinfo.jpeg_color_space == JCS_YCCK; 283 cinfo.jpeg_color_space == JCS_YCbCr || cinfo.jpeg_color_space == JCS_YCCK;
127 *bits_per_components = cinfo.data_precision; 284 bits_per_components = cinfo.data_precision;
285 if (icc_buf_ptr) {
286 *icc_buf_ptr = NULL;
287 }
288 if (icc_length) {
289 *icc_length = 0;
290 }
128 jpeg_destroy_decompress(&cinfo); 291 jpeg_destroy_decompress(&cinfo);
129 return true; 292 return TRUE;
130 } 293 }
131 294
132 class CCodec_JpegDecoder : public CCodec_ScanlineDecoder { 295 class CCodec_JpegDecoder : public CCodec_ScanlineDecoder {
133 public: 296 public:
134 CCodec_JpegDecoder(); 297 CCodec_JpegDecoder();
135 ~CCodec_JpegDecoder() override; 298 ~CCodec_JpegDecoder() override;
136 299
137 FX_BOOL Create(const uint8_t* src_buf, 300 FX_BOOL Create(const uint8_t* src_buf,
138 FX_DWORD src_size, 301 FX_DWORD src_size,
139 int width, 302 int width,
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 return NULL; 505 return NULL;
343 } 506 }
344 CCodec_JpegDecoder* pDecoder = new CCodec_JpegDecoder; 507 CCodec_JpegDecoder* pDecoder = new CCodec_JpegDecoder;
345 if (!pDecoder->Create(src_buf, src_size, width, height, nComps, 508 if (!pDecoder->Create(src_buf, src_size, width, height, nComps,
346 ColorTransform)) { 509 ColorTransform)) {
347 delete pDecoder; 510 delete pDecoder;
348 return NULL; 511 return NULL;
349 } 512 }
350 return pDecoder; 513 return pDecoder;
351 } 514 }
352 bool CCodec_JpegModule::LoadInfo(const uint8_t* src_buf, 515 FX_BOOL CCodec_JpegModule::LoadInfo(const uint8_t* src_buf,
353 FX_DWORD src_size, 516 FX_DWORD src_size,
354 int* width, 517 int& width,
355 int* height, 518 int& height,
356 int* num_components, 519 int& num_components,
357 int* bits_per_components, 520 int& bits_per_components,
358 bool* color_transform) { 521 FX_BOOL& color_transform,
359 return JpegLoadInfo(src_buf, src_size, width, height, num_components, 522 uint8_t** icc_buf_ptr,
360 bits_per_components, color_transform); 523 FX_DWORD* icc_length) {
524 return _JpegLoadInfo(src_buf, src_size, width, height, num_components,
525 bits_per_components, color_transform, icc_buf_ptr,
526 icc_length);
361 } 527 }
528 FX_BOOL CCodec_JpegModule::Encode(const CFX_DIBSource* pSource,
529 uint8_t*& dest_buf,
530 FX_STRSIZE& dest_size,
531 int quality,
532 const uint8_t* icc_buf,
533 FX_DWORD icc_length) {
534 if (pSource->GetBPP() < 8 || pSource->GetPalette())
535 return FALSE;
362 536
537 _JpegEncode(pSource, dest_buf, dest_size, quality, icc_buf, icc_length);
538 return TRUE;
539 }
363 struct FXJPEG_Context { 540 struct FXJPEG_Context {
364 jmp_buf m_JumpMark; 541 jmp_buf m_JumpMark;
365 jpeg_decompress_struct m_Info; 542 jpeg_decompress_struct m_Info;
366 jpeg_error_mgr m_ErrMgr; 543 jpeg_error_mgr m_ErrMgr;
367 jpeg_source_mgr m_SrcMgr; 544 jpeg_source_mgr m_SrcMgr;
368 unsigned int m_SkipSize; 545 unsigned int m_SkipSize;
369 void* (*m_AllocFunc)(unsigned int); 546 void* (*m_AllocFunc)(unsigned int);
370 void (*m_FreeFunc)(void*); 547 void (*m_FreeFunc)(void*);
371 }; 548 };
372 extern "C" { 549 extern "C" {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 uint8_t** avail_buf_ptr) { 656 uint8_t** avail_buf_ptr) {
480 if (avail_buf_ptr) { 657 if (avail_buf_ptr) {
481 *avail_buf_ptr = NULL; 658 *avail_buf_ptr = NULL;
482 if (((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer > 0) { 659 if (((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer > 0) {
483 *avail_buf_ptr = 660 *avail_buf_ptr =
484 (uint8_t*)((FXJPEG_Context*)pContext)->m_SrcMgr.next_input_byte; 661 (uint8_t*)((FXJPEG_Context*)pContext)->m_SrcMgr.next_input_byte;
485 } 662 }
486 } 663 }
487 return (FX_DWORD)((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer; 664 return (FX_DWORD)((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer;
488 } 665 }
OLDNEW
« no previous file with comments | « core/src/fxcodec/codec/fx_codec_flate.cpp ('k') | core/src/fxge/ge/fx_ge_ps.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698