14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Copyright 2014 PDFium Authors. All rights reserved. 24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be 34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// found in the LICENSE file. 44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <setjmp.h> 84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <memory> 104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <utility> 114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcodec/codec/codec_int.h" 134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcodec/fx_codec.h" 144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcrt/fx_safe_types.h" 154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxge/fx_dib.h" 164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "third_party/base/ptr_util.h" 174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannextern "C" { 194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#undef FAR 204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(USE_SYSTEM_LIBJPEG) 214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <jpeglib.h> 224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#elif defined(USE_LIBJPEG_TURBO) 234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "third_party/libjpeg_turbo/jpeglib.h" 244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "third_party/libjpeg/jpeglib.h" 264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannextern "C" { 304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void JpegScanSOI(const uint8_t** src_buf, uint32_t* src_size) { 324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (*src_size == 0) 334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t offset = 0; 364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (offset < *src_size - 1) { 374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((*src_buf)[offset] == 0xff && (*src_buf)[offset + 1] == 0xd8) { 384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *src_buf += offset; 394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *src_size -= offset; 404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann offset++; 434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void _src_do_nothing(struct jpeg_decompress_struct* cinfo) {} 474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void _error_fatal(j_common_ptr cinfo) { 494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann longjmp(*(jmp_buf*)cinfo->client_data, -1); 504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void _src_skip_data(struct jpeg_decompress_struct* cinfo, long num) { 534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (num > (long)cinfo->src->bytes_in_buffer) { 544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann _error_fatal((j_common_ptr)cinfo); 554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo->src->next_input_byte += num; 574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo->src->bytes_in_buffer -= num; 584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic boolean _src_fill_buffer(j_decompress_ptr cinfo) { 614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic boolean _src_resync(j_decompress_ptr cinfo, int desired) { 654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void _error_do_nothing(j_common_ptr cinfo) {} 694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void _error_do_nothing1(j_common_ptr cinfo, int) {} 714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void _error_do_nothing2(j_common_ptr cinfo, char*) {} 734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ 754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void _dest_do_nothing(j_compress_ptr cinfo) {} 764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic boolean _dest_empty(j_compress_ptr cinfo) { 784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define JPEG_MARKER_ICC (JPEG_APP0 + 2) 844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define JPEG_MARKER_MAXSIZE 0xFFFF 854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PDF_ENABLE_XFA 874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void JpegLoadAttribute(struct jpeg_decompress_struct* pInfo, 884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CFX_DIBAttribute* pAttribute) { 894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!pAttribute) 904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pAttribute->m_nXDPI = pInfo->X_density; 934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pAttribute->m_nYDPI = pInfo->Y_density; 944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pAttribute->m_wDPIUnit = pInfo->density_unit; 954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif // PDF_ENABLE_XFA 974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic bool JpegLoadInfo(const uint8_t* src_buf, 994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* width, 1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* height, 1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* num_components, 1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* bits_per_components, 1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool* color_transform) { 1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann JpegScanSOI(&src_buf, &src_size); 1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann struct jpeg_decompress_struct cinfo; 1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann struct jpeg_error_mgr jerr; 1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.error_exit = _error_fatal; 1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.emit_message = _error_do_nothing1; 1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.output_message = _error_do_nothing; 1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.format_message = _error_do_nothing2; 1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.reset_error_mgr = _error_do_nothing; 1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.trace_level = 0; 1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.err = &jerr; 1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jmp_buf mark; 1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.client_data = &mark; 1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(mark) == -1) 1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_create_decompress(&cinfo); 1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann struct jpeg_source_mgr src; 1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.init_source = _src_do_nothing; 1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.term_source = _src_do_nothing; 1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.skip_input_data = _src_skip_data; 1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.fill_input_buffer = _src_fill_buffer; 1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.resync_to_restart = _src_resync; 1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.bytes_in_buffer = src_size; 1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.next_input_byte = src_buf; 1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.src = &src; 1304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(mark) == -1) { 1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_destroy_decompress(&cinfo); 1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int ret = jpeg_read_header(&cinfo, true); 1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ret != JPEG_HEADER_OK) { 1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_destroy_decompress(&cinfo); 1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *width = cinfo.image_width; 1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *height = cinfo.image_height; 1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *num_components = cinfo.num_components; 1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *color_transform = 1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.jpeg_color_space == JCS_YCbCr || cinfo.jpeg_color_space == JCS_YCCK; 1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *bits_per_components = cinfo.data_precision; 1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_destroy_decompress(&cinfo); 1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannclass CCodec_JpegDecoder : public CCodec_ScanlineDecoder { 1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann public: 1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CCodec_JpegDecoder(); 1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ~CCodec_JpegDecoder() override; 1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool Create(const uint8_t* src_buf, 1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int width, 1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int height, 1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int nComps, 1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool ColorTransform); 1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann // CCodec_ScanlineDecoder 1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool v_Rewind() override; 1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* v_GetNextLine() override; 1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t GetSrcOffset() override; 1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool InitDecode(); 1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jmp_buf m_JmpBuf; 1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann struct jpeg_decompress_struct cinfo; 1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann struct jpeg_error_mgr jerr; 1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann struct jpeg_source_mgr src; 1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const uint8_t* m_SrcBuf; 1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t m_SrcSize; 1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* m_pScanlineBuf; 1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool m_bInited; 1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool m_bStarted; 1784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool m_bJpegTransform; 1794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann protected: 1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t m_nDefaultScaleDenom; 1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCCodec_JpegDecoder::CCodec_JpegDecoder() { 1854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pScanlineBuf = nullptr; 1864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bStarted = false; 1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bInited = false; 1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FXSYS_memset(&cinfo, 0, sizeof(cinfo)); 1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FXSYS_memset(&jerr, 0, sizeof(jerr)); 1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FXSYS_memset(&src, 0, sizeof(src)); 1914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nDefaultScaleDenom = 1; 1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCCodec_JpegDecoder::~CCodec_JpegDecoder() { 1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FX_Free(m_pScanlineBuf); 1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_bInited) 1974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_destroy_decompress(&cinfo); 1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_JpegDecoder::InitDecode() { 2014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.err = &jerr; 2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.client_data = &m_JmpBuf; 2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(m_JmpBuf) == -1) 2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_create_decompress(&cinfo); 2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bInited = true; 2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.src = &src; 2094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.bytes_in_buffer = m_SrcSize; 2104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.next_input_byte = m_SrcBuf; 2114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(m_JmpBuf) == -1) { 2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_destroy_decompress(&cinfo); 2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bInited = false; 2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.image_width = m_OrigWidth; 2174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.image_height = m_OrigHeight; 2184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int ret = jpeg_read_header(&cinfo, true); 2194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ret != JPEG_HEADER_OK) 2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 2214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cinfo.saw_Adobe_marker) 2234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bJpegTransform = true; 2244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cinfo.num_components == 3 && !m_bJpegTransform) 2264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.out_color_space = cinfo.jpeg_color_space; 2274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OrigWidth = cinfo.image_width; 2294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OrigHeight = cinfo.image_height; 2304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OutputWidth = m_OrigWidth; 2314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OutputHeight = m_OrigHeight; 2324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nDefaultScaleDenom = cinfo.scale_denom; 2334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 2344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 2354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_JpegDecoder::Create(const uint8_t* src_buf, 2374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 2384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int width, 2394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int height, 2404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int nComps, 2414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool ColorTransform) { 2424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann JpegScanSOI(&src_buf, &src_size); 2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_SrcBuf = src_buf; 2444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_SrcSize = src_size; 2454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.error_exit = _error_fatal; 2464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.emit_message = _error_do_nothing1; 2474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.output_message = _error_do_nothing; 2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.format_message = _error_do_nothing2; 2494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.reset_error_mgr = _error_do_nothing; 2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.init_source = _src_do_nothing; 2514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.term_source = _src_do_nothing; 2524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.skip_input_data = _src_skip_data; 2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.fill_input_buffer = _src_fill_buffer; 2544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src.resync_to_restart = _src_resync; 2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bJpegTransform = ColorTransform; 2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (src_size > 1 && 2574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FXSYS_memcmp(src_buf + src_size - 2, "\xFF\xD9", 2) != 0) { 2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((uint8_t*)src_buf)[src_size - 2] = 0xFF; 2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((uint8_t*)src_buf)[src_size - 1] = 0xD9; 2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OutputWidth = m_OrigWidth = width; 2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OutputHeight = m_OrigHeight = height; 2634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!InitDecode()) 2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cinfo.num_components < nComps) 2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((int)cinfo.image_width < width) 2704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 2714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_Pitch = 2734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (static_cast<uint32_t>(cinfo.image_width) * cinfo.num_components + 3) / 2744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4 * 4; 2754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); 2764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nComps = cinfo.num_components; 2774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bpc = 8; 2784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bStarted = false; 2794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 2814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_JpegDecoder::v_Rewind() { 2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_bStarted) { 2844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_destroy_decompress(&cinfo); 2854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!InitDecode()) { 2864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 2874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(m_JmpBuf) == -1) { 2904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.scale_denom = m_nDefaultScaleDenom; 2934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OutputWidth = m_OrigWidth; 2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_OutputHeight = m_OrigHeight; 2954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!jpeg_start_decompress(&cinfo)) { 2964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_destroy_decompress(&cinfo); 2974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 2984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((int)cinfo.output_width > m_OrigWidth) { 3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ASSERT(false); 3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bStarted = true; 3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannuint8_t* CCodec_JpegDecoder::v_GetNextLine() { 3084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(m_JmpBuf) == -1) 3094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 3104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int nlines = jpeg_read_scanlines(&cinfo, &m_pScanlineBuf, 1); 3124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nlines > 0 ? m_pScanlineBuf : nullptr; 3134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannuint32_t CCodec_JpegDecoder::GetSrcOffset() { 3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (uint32_t)(m_SrcSize - src.bytes_in_buffer); 3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstd::unique_ptr<CCodec_ScanlineDecoder> CCodec_JpegModule::CreateDecoder( 3204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const uint8_t* src_buf, 3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 3224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int width, 3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int height, 3244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int nComps, 3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool ColorTransform) { 3264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!src_buf || src_size == 0) 3274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 3284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann auto pDecoder = pdfium::MakeUnique<CCodec_JpegDecoder>(); 3304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!pDecoder->Create(src_buf, src_size, width, height, nComps, 3314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ColorTransform)) { 3324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 3334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return std::move(pDecoder); 3354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_JpegModule::LoadInfo(const uint8_t* src_buf, 3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* width, 3404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* height, 3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* num_components, 3424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* bits_per_components, 3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool* color_transform) { 3444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return JpegLoadInfo(src_buf, src_size, width, height, num_components, 3454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bits_per_components, color_transform); 3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstruct FXJPEG_Context { 3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jmp_buf m_JumpMark; 3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_decompress_struct m_Info; 3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_error_mgr m_ErrMgr; 3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_source_mgr m_SrcMgr; 3534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int m_SkipSize; 3544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann void* (*m_AllocFunc)(unsigned int); 3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann void (*m_FreeFunc)(void*); 3564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 3574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannextern "C" { 3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void _error_fatal1(j_common_ptr cinfo) { 3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann longjmp(((FXJPEG_Context*)cinfo->client_data)->m_JumpMark, -1); 3604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 3624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannextern "C" { 3634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void _src_skip_data1(struct jpeg_decompress_struct* cinfo, long num) { 3644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cinfo->src->bytes_in_buffer < (size_t)num) { 3654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((FXJPEG_Context*)cinfo->client_data)->m_SkipSize = 3664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (unsigned int)(num - cinfo->src->bytes_in_buffer); 3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo->src->bytes_in_buffer = 0; 3684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 3694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo->src->next_input_byte += num; 3704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo->src->bytes_in_buffer -= num; 3714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 3744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void* jpeg_alloc_func(unsigned int size) { 3754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return FX_Alloc(char, size); 3764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void jpeg_free_func(void* p) { 3784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FX_Free(p); 3794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannFXJPEG_Context* CCodec_JpegModule::Start() { 3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FXJPEG_Context* p = FX_Alloc(FXJPEG_Context, 1); 3824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_AllocFunc = jpeg_alloc_func; 3834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_FreeFunc = jpeg_free_func; 3844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_ErrMgr.error_exit = _error_fatal1; 3854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_ErrMgr.emit_message = _error_do_nothing1; 3864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_ErrMgr.output_message = _error_do_nothing; 3874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_ErrMgr.format_message = _error_do_nothing2; 3884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_ErrMgr.reset_error_mgr = _error_do_nothing; 3894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_SrcMgr.init_source = _src_do_nothing; 3904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_SrcMgr.term_source = _src_do_nothing; 3914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_SrcMgr.skip_input_data = _src_skip_data1; 3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_SrcMgr.fill_input_buffer = _src_fill_buffer; 3934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_SrcMgr.resync_to_restart = _src_resync; 3944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_Info.client_data = p; 3954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_Info.err = &p->m_ErrMgr; 3964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(p->m_JumpMark) == -1) { 3974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_create_decompress(&p->m_Info); 4004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_Info.src = &p->m_SrcMgr; 4014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p->m_SkipSize = 0; 4024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return p; 4034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 4044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CCodec_JpegModule::Finish(FXJPEG_Context* ctx) { 4064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_destroy_decompress(&ctx->m_Info); 4074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ctx->m_FreeFunc(ctx); 4084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 4094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CCodec_JpegModule::Input(FXJPEG_Context* ctx, 4114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const unsigned char* src_buf, 4124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size) { 4134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ctx->m_SkipSize) { 4144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ctx->m_SkipSize > src_size) { 4154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ctx->m_SrcMgr.bytes_in_buffer = 0; 4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ctx->m_SkipSize -= src_size; 4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 4184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src_size -= ctx->m_SkipSize; 4204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src_buf += ctx->m_SkipSize; 4214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ctx->m_SkipSize = 0; 4224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ctx->m_SrcMgr.next_input_byte = src_buf; 4244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ctx->m_SrcMgr.bytes_in_buffer = src_size; 4254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 4264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PDF_ENABLE_XFA 4284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint CCodec_JpegModule::ReadHeader(FXJPEG_Context* ctx, 4294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* width, 4304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* height, 4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* nComps, 4324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CFX_DIBAttribute* pAttribute) { 4334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else // PDF_ENABLE_XFA 4344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint CCodec_JpegModule::ReadHeader(FXJPEG_Context* ctx, 4354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* width, 4364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* height, 4374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int* nComps) { 4384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif // PDF_ENABLE_XFA 4394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(ctx->m_JumpMark) == -1) 4404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 4414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int ret = jpeg_read_header(&ctx->m_Info, true); 4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ret == JPEG_SUSPENDED) 4444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 2; 4454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ret != JPEG_HEADER_OK) 4464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 4474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *width = ctx->m_Info.image_width; 4494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *height = ctx->m_Info.image_height; 4504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *nComps = ctx->m_Info.num_components; 4514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PDF_ENABLE_XFA 4524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann JpegLoadAttribute(&ctx->m_Info, pAttribute); 4534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 4554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_JpegModule::StartScanline(FXJPEG_Context* ctx, int down_scale) { 4584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(ctx->m_JumpMark) == -1) 4594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 4604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ctx->m_Info.scale_denom = down_scale; 4624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return !!jpeg_start_decompress(&ctx->m_Info); 4634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 4644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_JpegModule::ReadScanline(FXJPEG_Context* ctx, 4664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned char* dest_buf) { 4674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (setjmp(ctx->m_JumpMark) == -1) 4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int nlines = jpeg_read_scanlines(&ctx->m_Info, &dest_buf, 1); 4714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nlines == 1; 4724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 4734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannuint32_t CCodec_JpegModule::GetAvailInput(FXJPEG_Context* ctx, 4754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t** avail_buf_ptr) { 4764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (avail_buf_ptr) { 4774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *avail_buf_ptr = nullptr; 4784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ctx->m_SrcMgr.bytes_in_buffer > 0) { 4794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *avail_buf_ptr = (uint8_t*)ctx->m_SrcMgr.next_input_byte; 4804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (uint32_t)ctx->m_SrcMgr.bytes_in_buffer; 4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ 4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define JPEG_BLOCK_SIZE 1048576 4874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_JpegModule::JpegEncode(const CFX_DIBSource* pSource, 4884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t** dest_buf, 4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FX_STRSIZE* dest_size) { 4904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann struct jpeg_error_mgr jerr; 4914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.error_exit = _error_do_nothing; 4924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.emit_message = _error_do_nothing1; 4934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.output_message = _error_do_nothing; 4944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.format_message = _error_do_nothing2; 4954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jerr.reset_error_mgr = _error_do_nothing; 4964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann struct jpeg_compress_struct cinfo; 4984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memset(&cinfo, 0, sizeof(cinfo)); 4994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.err = &jerr; 5004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_create_compress(&cinfo); 5014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int Bpp = pSource->GetBPP() / 8; 5024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t nComponents = Bpp >= 3 ? (pSource->IsCmykImage() ? 4 : 3) : 1; 5034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t pitch = pSource->GetPitch(); 5044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t width = pdfium::base::checked_cast<uint32_t>(pSource->GetWidth()); 5054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t height = pdfium::base::checked_cast<uint32_t>(pSource->GetHeight()); 5064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FX_SAFE_UINT32 safe_buf_len = width; 5074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann safe_buf_len *= height; 5084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann safe_buf_len *= nComponents; 5094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann safe_buf_len += 1024; 5104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!safe_buf_len.IsValid()) 5114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 5124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t dest_buf_length = safe_buf_len.ValueOrDie(); 5144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_buf = FX_TryAlloc(uint8_t, dest_buf_length); 5154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int MIN_TRY_BUF_LEN = 1024; 5164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (!(*dest_buf) && dest_buf_length > MIN_TRY_BUF_LEN) { 5174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf_length >>= 1; 5184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_buf = FX_TryAlloc(uint8_t, dest_buf_length); 5194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!(*dest_buf)) 5214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 5224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann struct jpeg_destination_mgr dest; 5244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest.init_destination = _dest_do_nothing; 5254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest.term_destination = _dest_do_nothing; 5264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest.empty_output_buffer = _dest_empty; 5274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest.next_output_byte = *dest_buf; 5284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest.free_in_buffer = dest_buf_length; 5294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.dest = &dest; 5304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.image_width = width; 5314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.image_height = height; 5324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.input_components = nComponents; 5334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (nComponents == 1) { 5344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.in_color_space = JCS_GRAYSCALE; 5354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else if (nComponents == 3) { 5364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.in_color_space = JCS_RGB; 5374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 5384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cinfo.in_color_space = JCS_CMYK; 5394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* line_buf = nullptr; 5414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (nComponents > 1) 5424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann line_buf = FX_Alloc2D(uint8_t, width, nComponents); 5434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_set_defaults(&cinfo); 5454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_start_compress(&cinfo, TRUE); 5464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann JSAMPROW row_pointer[1]; 5474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann JDIMENSION row; 5484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (cinfo.next_scanline < cinfo.image_height) { 5494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const uint8_t* src_scan = pSource->GetScanline(cinfo.next_scanline); 5504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (nComponents > 1) { 5514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* dest_scan = line_buf; 5524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (nComponents == 3) { 5534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (uint32_t i = 0; i < width; i++) { 5544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_scan[0] = src_scan[2]; 5554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_scan[1] = src_scan[1]; 5564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_scan[2] = src_scan[0]; 5574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_scan += 3; 5584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann src_scan += Bpp; 5594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 5614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (uint32_t i = 0; i < pitch; i++) { 5624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_scan++ = ~*src_scan++; 5634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_pointer[0] = line_buf; 5664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 5674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_pointer[0] = (uint8_t*)src_scan; 5684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row = cinfo.next_scanline; 5704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_write_scanlines(&cinfo, row_pointer, 1); 5714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cinfo.next_scanline == row) { 5724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_buf = 5734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FX_Realloc(uint8_t, *dest_buf, dest_buf_length + JPEG_BLOCK_SIZE); 5744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest.next_output_byte = *dest_buf + dest_buf_length - dest.free_in_buffer; 5754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf_length += JPEG_BLOCK_SIZE; 5764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest.free_in_buffer += JPEG_BLOCK_SIZE; 5774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_finish_compress(&cinfo); 5804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jpeg_destroy_compress(&cinfo); 5814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FX_Free(line_buf); 5824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_size = dest_buf_length - (FX_STRSIZE)dest.free_in_buffer; 5834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 5854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 5864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 587