diff options
author | Bo Xu <bo_xu@foxitsoftware.com> | 2014-10-28 23:03:33 -0700 |
---|---|---|
committer | Bo Xu <bo_xu@foxitsoftware.com> | 2014-11-03 11:10:11 -0800 |
commit | fdc00a7042d912aafaabddae4d9c84199921ef23 (patch) | |
tree | 32ab8ac91cc68d2cd15b9168782a71b3f3f5e7b9 /core/src/fxcodec/codec/fx_codec_jpeg.cpp | |
parent | e9b38fa38de2c95d8260be31c57d9272c4d127ed (diff) | |
download | pdfium-fdc00a7042d912aafaabddae4d9c84199921ef23.tar.xz |
Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
Diffstat (limited to 'core/src/fxcodec/codec/fx_codec_jpeg.cpp')
-rw-r--r-- | core/src/fxcodec/codec/fx_codec_jpeg.cpp | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/core/src/fxcodec/codec/fx_codec_jpeg.cpp b/core/src/fxcodec/codec/fx_codec_jpeg.cpp index 489f099bf8..95770ea26e 100644 --- a/core/src/fxcodec/codec/fx_codec_jpeg.cpp +++ b/core/src/fxcodec/codec/fx_codec_jpeg.cpp @@ -73,6 +73,68 @@ extern "C" { #define JPEG_MARKER_AUTHORTIME (JPEG_APP0 + 3) #define JPEG_MARKER_MAXSIZE 0xFFFF #define JPEG_OVERHEAD_LEN 14 +static FX_BOOL _JpegIsIccMarker(jpeg_saved_marker_ptr marker) +{ + if (marker->marker == JPEG_MARKER_ICC && + marker->data_length >= JPEG_OVERHEAD_LEN && + (FXSYS_memcmp32(marker->data, "\x49\x43\x43\x5f\x50\x52\x4f\x46\x49\x4c\x45\x00", 12) == 0)) { + return TRUE; + } + return FALSE; +} +static FX_BOOL _JpegLoadIccProfile(j_decompress_ptr cinfo, FX_LPBYTE* icc_buf_ptr, FX_DWORD* icc_length) +{ + if(icc_buf_ptr == NULL || icc_length == NULL) { + return FALSE; + } + *icc_buf_ptr = NULL; + *icc_length = 0; + FX_LPBYTE icc_data_ptr = NULL; + FX_DWORD icc_data_len = 0; + FX_BYTE count_icc_marker = 0; + FX_BYTE num_icc_marker = 0; + jpeg_saved_marker_ptr marker_list[256] = {NULL}; + for (jpeg_saved_marker_ptr cur_marker = cinfo->marker_list; + cur_marker != NULL; + cur_marker = cur_marker->next) { + if(_JpegIsIccMarker(cur_marker)) { + if(count_icc_marker == 0) { + num_icc_marker = cur_marker->data[13]; + } else if(num_icc_marker != cur_marker->data[13]) { + return FALSE; + } + int sn = cur_marker->data[12] - 1; + if(sn < 0 || sn >= num_icc_marker) { + return FALSE; + } + if(marker_list[sn] == NULL) { + marker_list[sn] = cur_marker; + } else { + return FALSE; + } + count_icc_marker ++; + icc_data_len += (cur_marker->data_length - JPEG_OVERHEAD_LEN); + } + } + if(count_icc_marker != num_icc_marker) { + return FALSE; + } + if(num_icc_marker == 0) { + return TRUE; + } + icc_data_ptr = FX_Alloc(FX_BYTE, icc_data_len); + if(icc_buf_ptr == NULL) { + return FALSE; + } + *icc_buf_ptr = icc_data_ptr; + *icc_length = icc_data_len; + for (int idx = 0; idx < num_icc_marker; idx++) { + icc_data_len = marker_list[idx]->data_length - JPEG_OVERHEAD_LEN; + FXSYS_memcpy32(icc_data_ptr, marker_list[idx]->data + JPEG_OVERHEAD_LEN, icc_data_len); + icc_data_ptr += icc_data_len; + } + return TRUE; +} static FX_BOOL _JpegEmbedIccProfile(j_compress_ptr cinfo, FX_LPCBYTE icc_buf_ptr, FX_DWORD icc_length) { if(icc_buf_ptr == NULL || icc_length == 0) { @@ -207,6 +269,17 @@ static void _JpegEncode(const CFX_DIBSource* pSource, FX_LPBYTE& dest_buf, FX_ST } dest_size = dest_buf_length - (FX_STRSIZE)dest.free_in_buffer; } +static void _JpegLoadAttribute(struct jpeg_decompress_struct* pInfo, CFX_DIBAttribute* pAttribute) +{ + if (pInfo == NULL || pAttribute == NULL) { + return; + } + if (pAttribute) { + pAttribute->m_nXDPI = pInfo->X_density; + pAttribute->m_nYDPI = pInfo->Y_density; + pAttribute->m_wDPIUnit = pInfo->density_unit; + } +} static FX_BOOL _JpegLoadInfo(FX_LPCBYTE src_buf, FX_DWORD src_size, int& width, int& height, int& num_components, int& bits_per_components, FX_BOOL& color_transform, FX_LPBYTE* icc_buf_ptr, FX_DWORD* icc_length) @@ -613,10 +686,10 @@ void CCodec_JpegModule::Input(void* pContext, const unsigned char* src_buf, FX_D p->m_SrcMgr.next_input_byte = src_buf; p->m_SrcMgr.bytes_in_buffer = src_size; } -int CCodec_JpegModule::ReadHeader(void* pContext, int* width, int* height, int* nComps) +int CCodec_JpegModule::ReadHeader(void* pContext, int* width, int* height, int* nComps, CFX_DIBAttribute* pAttribute) { if (m_pExtProvider) { - return m_pExtProvider->ReadHeader(pContext, width, height, nComps); + return m_pExtProvider->ReadHeader(pContext, width, height, nComps, pAttribute); } FXJPEG_Context* p = (FXJPEG_Context*)pContext; if (setjmp(p->m_JumpMark) == -1) { @@ -632,6 +705,7 @@ int CCodec_JpegModule::ReadHeader(void* pContext, int* width, int* height, int* *width = p->m_Info.image_width; *height = p->m_Info.image_height; *nComps = p->m_Info.num_components; + _JpegLoadAttribute(&p->m_Info, pAttribute); return 0; } FX_BOOL CCodec_JpegModule::StartScanline(void* pContext, int down_scale) |