in turbojpeg.c [2418:2556]
DLLEXPORT int tj3DecodeYUVPlanes8(tjhandle handle,
const unsigned char * const *srcPlanes,
const int *strides, unsigned char *dstBuf,
int width, int pitch, int height,
int pixelFormat)
{
static const char FUNCTION_NAME[] = "tj3DecodeYUVPlanes8";
JSAMPROW *row_pointer = NULL;
JSAMPLE *_tmpbuf[MAX_COMPONENTS];
JSAMPROW *tmpbuf[MAX_COMPONENTS], *inbuf[MAX_COMPONENTS];
int i, retval = 0, row, pw0, ph0, pw[MAX_COMPONENTS], ph[MAX_COMPONENTS];
JSAMPLE *ptr;
jpeg_component_info *compptr;
int (*old_read_markers) (j_decompress_ptr);
void (*old_reset_marker_reader) (j_decompress_ptr);
GET_DINSTANCE(handle);
for (i = 0; i < MAX_COMPONENTS; i++) {
tmpbuf[i] = NULL; _tmpbuf[i] = NULL; inbuf[i] = NULL;
}
if ((this->init & DECOMPRESS) == 0)
THROW("Instance has not been initialized for decompression");
if (!srcPlanes || !srcPlanes[0] || dstBuf == NULL || width <= 0 ||
pitch < 0 || height <= 0 || pixelFormat < 0 || pixelFormat >= TJ_NUMPF)
THROW("Invalid argument");
if (this->subsamp != TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2]))
THROW("Invalid argument");
if (setjmp(this->jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error. */
retval = -1; goto bailout;
}
if (this->subsamp == TJSAMP_UNKNOWN)
THROW("TJPARAM_SUBSAMP must be specified");
if (pixelFormat == TJPF_CMYK)
THROW("Cannot decode YUV images into packed-pixel CMYK images.");
if (pitch == 0) pitch = width * tjPixelSize[pixelFormat];
dinfo->image_width = width;
dinfo->image_height = height;
dinfo->progressive_mode = dinfo->inputctl->has_multiple_scans = FALSE;
dinfo->Ss = dinfo->Ah = dinfo->Al = 0;
dinfo->Se = DCTSIZE2 - 1;
setDecodeDefaults(this, pixelFormat);
old_read_markers = dinfo->marker->read_markers;
dinfo->marker->read_markers = my_read_markers;
old_reset_marker_reader = dinfo->marker->reset_marker_reader;
dinfo->marker->reset_marker_reader = my_reset_marker_reader;
jpeg_read_header(dinfo, TRUE);
dinfo->marker->read_markers = old_read_markers;
dinfo->marker->reset_marker_reader = old_reset_marker_reader;
this->dinfo.out_color_space = pf2cs[pixelFormat];
this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW;
dinfo->do_fancy_upsampling = FALSE;
dinfo->Se = DCTSIZE2 - 1;
jinit_master_decompress(dinfo);
(*dinfo->upsample->start_pass) (dinfo);
pw0 = PAD(width, dinfo->max_h_samp_factor);
ph0 = PAD(height, dinfo->max_v_samp_factor);
if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat];
if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph0)) == NULL)
THROW("Memory allocation failure");
for (i = 0; i < height; i++) {
if (this->bottomUp)
row_pointer[i] = &dstBuf[(height - i - 1) * (size_t)pitch];
else
row_pointer[i] = &dstBuf[i * (size_t)pitch];
}
if (height < ph0)
for (i = height; i < ph0; i++) row_pointer[i] = row_pointer[height - 1];
for (i = 0; i < dinfo->num_components; i++) {
compptr = &dinfo->comp_info[i];
_tmpbuf[i] =
(JSAMPLE *)malloc(PAD(compptr->width_in_blocks * DCTSIZE, 32) *
compptr->v_samp_factor + 32);
if (!_tmpbuf[i])
THROW("Memory allocation failure");
tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * compptr->v_samp_factor);
if (!tmpbuf[i])
THROW("Memory allocation failure");
for (row = 0; row < compptr->v_samp_factor; row++) {
unsigned char *_tmpbuf_aligned =
(unsigned char *)PAD((JUINTPTR)_tmpbuf[i], 32);
tmpbuf[i][row] =
&_tmpbuf_aligned[PAD(compptr->width_in_blocks * DCTSIZE, 32) * row];
}
pw[i] = pw0 * compptr->h_samp_factor / dinfo->max_h_samp_factor;
ph[i] = ph0 * compptr->v_samp_factor / dinfo->max_v_samp_factor;
inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]);
if (!inbuf[i])
THROW("Memory allocation failure");
ptr = (JSAMPLE *)srcPlanes[i];
for (row = 0; row < ph[i]; row++) {
inbuf[i][row] = ptr;
ptr += (strides && strides[i] != 0) ? strides[i] : pw[i];
}
}
if (setjmp(this->jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error. */
retval = -1; goto bailout;
}
for (row = 0; row < ph0; row += dinfo->max_v_samp_factor) {
JDIMENSION inrow = 0, outrow = 0;
for (i = 0, compptr = dinfo->comp_info; i < dinfo->num_components;
i++, compptr++)
jcopy_sample_rows(inbuf[i],
row * compptr->v_samp_factor / dinfo->max_v_samp_factor, tmpbuf[i], 0,
compptr->v_samp_factor, pw[i]);
(dinfo->upsample->upsample) (dinfo, tmpbuf, &inrow,
dinfo->max_v_samp_factor, &row_pointer[row],
&outrow, dinfo->max_v_samp_factor);
}
jpeg_abort_decompress(dinfo);
bailout:
if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo);
free(row_pointer);
for (i = 0; i < MAX_COMPONENTS; i++) {
free(tmpbuf[i]);
free(_tmpbuf[i]);
free(inbuf[i]);
}
if (this->jerr.warning) retval = -1;
return retval;
}