blob: 9f06ecf514352c17f49ccdb089f95a9466ee5e7e [file]
// Copyright 2020 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "core/fxcodec/jpeg/jpeg_common.h"
#include "core/fxcrt/compiler_specific.h"
// This is a thin C wrapper around the JPEG API to avoid calling setjmp() from
// C++ code.
boolean jpeg_common_create_decompress(JpegCommon* jpeg_common) {
if (setjmp(jpeg_common->jmpbuf) == -1) {
return FALSE;
}
jpeg_create_decompress(&jpeg_common->cinfo);
return TRUE;
}
void jpeg_common_destroy_decompress(JpegCommon* jpeg_common) {
jpeg_destroy_decompress(&jpeg_common->cinfo);
}
boolean jpeg_common_start_decompress(JpegCommon* jpeg_common) {
if (setjmp(jpeg_common->jmpbuf) == -1) {
return FALSE;
}
return jpeg_start_decompress(&jpeg_common->cinfo);
}
int jpeg_common_read_header(JpegCommon* jpeg_common, boolean flag) {
if (setjmp(jpeg_common->jmpbuf) == -1) {
return -1;
}
return jpeg_read_header(&jpeg_common->cinfo, flag);
}
int jpeg_common_read_scanlines(JpegCommon* jpeg_common,
void* buf,
unsigned int count) {
if (setjmp(jpeg_common->jmpbuf) == -1) {
return -1;
}
return jpeg_read_scanlines(&jpeg_common->cinfo, buf, count);
}
void jpeg_common_src_do_nothing(j_decompress_ptr cinfo) {}
boolean jpeg_common_src_fill_buffer(j_decompress_ptr cinfo) {
return FALSE;
}
boolean jpeg_common_src_resync(j_decompress_ptr cinfo, int desired) {
return FALSE;
}
void jpeg_common_src_skip_data_or_record(j_decompress_ptr cinfo, long num) {
if (cinfo->src->bytes_in_buffer < (size_t)num) {
JpegCommon* pCommon = (JpegCommon*)(cinfo->client_data);
pCommon->skip_size = (unsigned int)(num - cinfo->src->bytes_in_buffer);
cinfo->src->bytes_in_buffer = 0;
} else {
// SAFETY: required from library during callback.
UNSAFE_BUFFERS(cinfo->src->next_input_byte += num);
cinfo->src->bytes_in_buffer -= num;
}
}
void jpeg_common_src_skip_data_or_trap(j_decompress_ptr cinfo, long num) {
if (num > (long)cinfo->src->bytes_in_buffer) {
jpeg_common_error_fatal((j_common_ptr)cinfo);
}
// SAFETY: required from library API as checked above.
UNSAFE_BUFFERS(cinfo->src->next_input_byte += num);
cinfo->src->bytes_in_buffer -= num;
}
void jpeg_common_error_do_nothing(j_common_ptr cinfo) {}
void jpeg_common_error_do_nothing_int(j_common_ptr cinfo, int arg) {}
void jpeg_common_error_do_nothing_char(j_common_ptr cinfo, char* arg) {}
void jpeg_common_error_fatal(j_common_ptr cinfo) {
JpegCommon* pCommon = (JpegCommon*)(cinfo->client_data);
longjmp(pCommon->jmpbuf, -1);
}
#if BUILDFLAG(IS_WIN)
boolean jpeg_common_create_compress(JpegCompressCommon* jpeg_compress) {
if (setjmp(jpeg_compress->jmpbuf) == -1) {
return FALSE;
}
jpeg_compress->cinfo.err = &jpeg_compress->error_mgr;
jpeg_compress->cinfo.client_data = jpeg_compress;
jpeg_compress->error_mgr.error_exit = jpeg_common_error_fatal;
jpeg_compress->error_mgr.emit_message = jpeg_common_error_do_nothing_int;
jpeg_compress->error_mgr.output_message = jpeg_common_error_do_nothing;
jpeg_compress->error_mgr.format_message = jpeg_common_error_do_nothing_char;
jpeg_compress->error_mgr.reset_error_mgr = jpeg_common_error_do_nothing;
jpeg_create_compress(&jpeg_compress->cinfo);
jpeg_compress->dest_mgr.init_destination = jpeg_common_dest_do_nothing;
jpeg_compress->dest_mgr.term_destination = jpeg_common_dest_do_nothing;
jpeg_compress->dest_mgr.empty_output_buffer = jpeg_common_dest_empty;
jpeg_compress->cinfo.dest = &jpeg_compress->dest_mgr;
return TRUE;
}
void jpeg_common_destroy_compress(JpegCompressCommon* jpeg_compress) {
jpeg_destroy_compress(&jpeg_compress->cinfo);
}
boolean jpeg_common_set_defaults(JpegCompressCommon* jpeg_compress) {
if (setjmp(jpeg_compress->jmpbuf) == -1) {
return FALSE;
}
jpeg_set_defaults(&jpeg_compress->cinfo);
return TRUE;
}
boolean jpeg_common_start_compress(JpegCompressCommon* jpeg_compress,
boolean write_all_tables) {
if (setjmp(jpeg_compress->jmpbuf) == -1) {
return FALSE;
}
jpeg_start_compress(&jpeg_compress->cinfo, write_all_tables);
return TRUE;
}
int jpeg_common_write_scanlines(JpegCompressCommon* jpeg_compress,
JSAMPROW* scanlines,
unsigned int num_lines) {
if (setjmp(jpeg_compress->jmpbuf) == -1) {
return -1;
}
return (int)jpeg_write_scanlines(&jpeg_compress->cinfo, scanlines, num_lines);
}
boolean jpeg_common_finish_compress(JpegCompressCommon* jpeg_compress) {
if (setjmp(jpeg_compress->jmpbuf) == -1) {
return FALSE;
}
jpeg_finish_compress(&jpeg_compress->cinfo);
return TRUE;
}
void jpeg_common_dest_do_nothing(j_compress_ptr cinfo) {}
boolean jpeg_common_dest_empty(j_compress_ptr cinfo) {
return FALSE;
}
#endif // BUILDFLAG(IS_WIN)