36 #include <libopenraw++/bitmapdata.h>
37 #include "io/stream.h"
39 #include "jfifcontainer.h"
43 using namespace Debug;
52 struct JPEG::jpeg_source_mgr pub;
58 JFIFContainer::JFIFContainer(
IO::Stream *_file, off_t offset)
63 setEndian(ENDIAN_BIG);
69 m_cinfo.err = JPEG::jpeg_std_error(&m_jerr);
70 m_jerr.error_exit = &j_error_exit;
71 JPEG::jpeg_create_decompress(&m_cinfo);
76 (*m_cinfo.mem->alloc_small)((JPEG::j_common_ptr)&m_cinfo,
79 m_cinfo.src = (JPEG::jpeg_source_mgr*)src;
80 src->
pub.init_source = j_init_source;
81 src->
pub.fill_input_buffer = j_fill_input_buffer;
82 src->
pub.skip_input_data = j_skip_input_data;
83 src->
pub.resync_to_restart = JPEG::jpeg_resync_to_restart;
84 src->
pub.term_source = j_term_source;
86 src->
pub.bytes_in_buffer = 0;
87 src->
pub.next_input_byte = NULL;
88 src->buf = (JPEG::JOCTET*)(*m_cinfo.mem->alloc_small)
89 ((JPEG::j_common_ptr)&m_cinfo,
91 BUF_SIZE *
sizeof(JPEG::JOCTET));
96 JPEG::jpeg_destroy_decompress(&m_cinfo);
100 bool JFIFContainer::getDimensions(uint32_t &x, uint32_t &y)
102 if(!m_headerLoaded) {
103 if (_loadHeader() == 0) {
104 Trace(DEBUG1) <<
"load header failed\n";
108 x = m_cinfo.output_width;
109 y = m_cinfo.output_height;
114 bool JFIFContainer::getDecompressedData(BitmapData &data)
116 if(!m_headerLoaded) {
117 if (_loadHeader() == 0) {
118 Trace(DEBUG1) <<
"load header failed\n";
122 if (::setjmp(m_jpegjmp) != 0) {
125 JPEG::jpeg_start_decompress(&m_cinfo);
126 int row_size = m_cinfo.output_width * m_cinfo.output_components;
127 char *dataPtr = (
char*)data.allocData(row_size * m_cinfo.output_height);
128 char *currentPtr = dataPtr;
129 JPEG::JSAMPARRAY buffer = (*m_cinfo.mem->alloc_sarray)((JPEG::j_common_ptr)&m_cinfo,
130 JPOOL_IMAGE, row_size,
132 while (m_cinfo.output_scanline < m_cinfo.output_height) {
133 jpeg_read_scanlines(&m_cinfo, buffer, 1);
134 memcpy(currentPtr, buffer, row_size);
135 currentPtr += row_size;
137 data.setDimensions(m_cinfo.output_width, m_cinfo.output_height);
139 JPEG::jpeg_finish_decompress(&m_cinfo);
144 int JFIFContainer::_loadHeader()
147 if (::setjmp(m_jpegjmp) == 0) {
148 ret = JPEG::jpeg_read_header(&m_cinfo, TRUE);
151 JPEG::jpeg_calc_output_dimensions(&m_cinfo);
153 m_headerLoaded = (ret == 1);
158 void JFIFContainer::j_error_exit(JPEG::j_common_ptr cinfo)
160 (*cinfo->err->output_message) (cinfo);
161 JFIFContainer *
self = ((jpeg_src_t *)(((JPEG::j_decompress_ptr)cinfo)->src))->
self;
162 ::longjmp(
self->m_jpegjmp, 1);
165 void JFIFContainer::j_init_source(JPEG::j_decompress_ptr)
171 JFIFContainer::j_fill_input_buffer(JPEG::j_decompress_ptr cinfo)
173 jpeg_src_t *src = (jpeg_src_t*)cinfo->src;
174 JFIFContainer *
self = src->self;
175 int n =
self->file()->
read(src->buf, BUF_SIZE *
sizeof(*src->buf));
177 src->pub.next_input_byte = src->buf;
178 src->pub.bytes_in_buffer = n;
181 src->pub.next_input_byte = NULL;
182 src->pub.bytes_in_buffer = 0;
188 void JFIFContainer::j_skip_input_data(JPEG::j_decompress_ptr cinfo,
191 jpeg_src_t *src = (jpeg_src_t*)cinfo->src;
193 while ((
size_t)num_bytes > src->pub.bytes_in_buffer) {
194 num_bytes -= src->pub.bytes_in_buffer;
195 j_fill_input_buffer(cinfo);
197 src->pub.next_input_byte += (size_t) num_bytes;
198 src->pub.bytes_in_buffer -= (size_t) num_bytes;
203 void JFIFContainer::j_term_source(JPEG::j_decompress_ptr)
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
struct JPEG::jpeg_source_mgr pub
virtual int read(void *buf, size_t count)=0
base virtual class for IO