blob: 8309999a8fb0a6317621faf9367b7e8578841c49 [file]
#include "dng_jpeg_memory_source.h"
#if qDNGUseLibJPEG
#include "dng_safe_arithmetic.h"
namespace {
void InitSource(j_decompress_ptr /* cinfo */)
{
// No initialization necessary.
}
boolean FillInputBuffer(j_decompress_ptr cinfo)
{
// We already filled the buffer with all of the data when the source was
// initialized, so we can't get any more data.
ERREXIT(cinfo, JERR_INPUT_EOF);
return FALSE;
}
void SkipInputData(j_decompress_ptr cinfo, long num_bytes)
{
if (num_bytes > 0)
{
// Convert num_bytes to a size_t.
// We've established that num_bytes is positive, to it's safe to cast it
// to an unsigned long.
size_t num_bytes_as_size_t = 0;
try
{
ConvertUnsigned(static_cast<unsigned long>(num_bytes),
&num_bytes_as_size_t);
}
catch (const dng_exception &e)
{
ERREXIT(cinfo, JERR_INPUT_EOF);
return;
}
jpeg_source_mgr *source_manager =
reinterpret_cast<jpeg_source_mgr *>(cinfo->src);
// Advance the current position by the given number of bytes.
if (num_bytes_as_size_t <= source_manager->bytes_in_buffer)
{
source_manager->bytes_in_buffer -= num_bytes_as_size_t;
source_manager->next_input_byte += num_bytes_as_size_t;
}
else
{
// Tried to read beyond the end of the buffer.
ERREXIT(cinfo, JERR_INPUT_EOF);
return;
}
}
}
boolean ResyncToRestart(j_decompress_ptr /* cinfo */, int /* desired */)
{
// Can't resync.
return FALSE;
}
void TermSource(j_decompress_ptr /* cinfo */)
{
// No termination necessary.
}
} // namespace
jpeg_source_mgr CreateJpegMemorySource(const uint8 *buffer, size_t size)
{
jpeg_source_mgr source;
source.next_input_byte = reinterpret_cast<const JOCTET *>(buffer);
source.bytes_in_buffer = size;
// Initialize function pointers.
source.init_source = InitSource;
source.fill_input_buffer = FillInputBuffer;
source.skip_input_data = SkipInputData;
source.resync_to_restart = ResyncToRestart;
source.term_source = TermSource;
return source;
}
#endif // qDNGUseLibJPEG