dinfo.raw_data_out = TRUE;
jpeg_start_decompress(&dinfo);
- /* We do not handle anything but YCbCr images (yet?). */
- if (dinfo.num_components != 3) {
+ if (dinfo.num_components != 1 && dinfo.num_components != 3) {
qscale_destroy(img);
return NULL;
}
+ img->num_components = dinfo.num_components;
img->width = dinfo.image_width;
img->height = dinfo.image_height;
img->w0 = dinfo.image_width * dinfo.comp_info[0].h_samp_factor / dinfo.max_h_samp_factor;
img->h0 = dinfo.image_height * dinfo.comp_info[0].v_samp_factor / dinfo.max_v_samp_factor;
- img->w1 = dinfo.image_width * dinfo.comp_info[1].h_samp_factor / dinfo.max_h_samp_factor;
- img->h1 = dinfo.image_height * dinfo.comp_info[1].v_samp_factor / dinfo.max_v_samp_factor;
+ if (img->num_components == 3) {
+ img->w1 = dinfo.image_width * dinfo.comp_info[1].h_samp_factor / dinfo.max_h_samp_factor;
+ img->h1 = dinfo.image_height * dinfo.comp_info[1].v_samp_factor / dinfo.max_v_samp_factor;
- img->w2 = dinfo.image_width * dinfo.comp_info[2].h_samp_factor / dinfo.max_h_samp_factor;
- img->h2 = dinfo.image_height * dinfo.comp_info[2].v_samp_factor / dinfo.max_v_samp_factor;
+ img->w2 = dinfo.image_width * dinfo.comp_info[2].h_samp_factor / dinfo.max_h_samp_factor;
+ img->h2 = dinfo.image_height * dinfo.comp_info[2].v_samp_factor / dinfo.max_v_samp_factor;
+ }
img->samp_h0 = dinfo.comp_info[0].h_samp_factor;
img->samp_v0 = dinfo.comp_info[0].v_samp_factor;
- img->samp_h1 = dinfo.comp_info[1].h_samp_factor;
- img->samp_v1 = dinfo.comp_info[1].v_samp_factor;
+ if (img->num_components == 3) {
+ img->samp_h1 = dinfo.comp_info[1].h_samp_factor;
+ img->samp_v1 = dinfo.comp_info[1].v_samp_factor;
- img->samp_h2 = dinfo.comp_info[2].h_samp_factor;
- img->samp_v2 = dinfo.comp_info[2].v_samp_factor;
+ img->samp_h2 = dinfo.comp_info[2].h_samp_factor;
+ img->samp_v2 = dinfo.comp_info[2].v_samp_factor;
+ }
img->data_y = (JSAMPLE*)memalign(16, dinfo.comp_info[0].height_in_blocks * dinfo.comp_info[0].width_in_blocks * DCTSIZE * DCTSIZE);
- img->data_cb = (JSAMPLE*)memalign(16, dinfo.comp_info[1].height_in_blocks * dinfo.comp_info[1].width_in_blocks * DCTSIZE * DCTSIZE);
- img->data_cr = (JSAMPLE*)memalign(16, dinfo.comp_info[2].height_in_blocks * dinfo.comp_info[2].width_in_blocks * DCTSIZE * DCTSIZE);
-
- if (img->data_y == NULL || img->data_cb == NULL || img->data_cr == NULL) {
+ if (img->data_y == NULL) {
qscale_destroy(img);
return NULL;
}
+ if (img->num_components == 3) {
+ img->data_cb = (JSAMPLE*)memalign(16, dinfo.comp_info[1].height_in_blocks * dinfo.comp_info[1].width_in_blocks * DCTSIZE * DCTSIZE);
+ img->data_cr = (JSAMPLE*)memalign(16, dinfo.comp_info[2].height_in_blocks * dinfo.comp_info[2].width_in_blocks * DCTSIZE * DCTSIZE);
+ if (img->data_cb == NULL || img->data_cr == NULL) {
+ qscale_destroy(img);
+ return NULL;
+ }
+ }
+
int total_lines = 0, blocks = 0;
while (total_lines < dinfo.comp_info[0].height_in_blocks * DCTSIZE) {
unsigned max_lines = dinfo.max_v_samp_factor * DCTSIZE;
int i;
for (i = 0; i < max_lines; ++i) {
y_row_ptrs[i] = img->data_y + (i+blocks*DCTSIZE*dinfo.comp_info[0].v_samp_factor) * dinfo.comp_info[0].width_in_blocks * DCTSIZE;
- cb_row_ptrs[i] = img->data_cb + (i+blocks*DCTSIZE*dinfo.comp_info[1].v_samp_factor) * dinfo.comp_info[1].width_in_blocks * DCTSIZE;
- cr_row_ptrs[i] = img->data_cr + (i+blocks*DCTSIZE*dinfo.comp_info[2].v_samp_factor) * dinfo.comp_info[2].width_in_blocks * DCTSIZE;
+ if (img->num_components == 3) {
+ cb_row_ptrs[i] = img->data_cb + (i+blocks*DCTSIZE*dinfo.comp_info[1].v_samp_factor) * dinfo.comp_info[1].width_in_blocks * DCTSIZE;
+ cr_row_ptrs[i] = img->data_cr + (i+blocks*DCTSIZE*dinfo.comp_info[2].v_samp_factor) * dinfo.comp_info[2].width_in_blocks * DCTSIZE;
+ }
}
total_lines += max_lines;
dst->width = width;
dst->height = height;
+ dst->num_components = src->num_components;
unsigned max_samp_h, max_samp_v;
max_samp_h = samp_h0;
- if (samp_h1 > max_samp_h)
- max_samp_h = samp_h1;
- if (samp_h2 > max_samp_h)
- max_samp_h = samp_h2;
+ if (src->num_components == 3) {
+ if (samp_h1 > max_samp_h)
+ max_samp_h = samp_h1;
+ if (samp_h2 > max_samp_h)
+ max_samp_h = samp_h2;
+ }
max_samp_v = samp_v0;
- if (samp_v1 > max_samp_v)
- max_samp_v = samp_v1;
- if (samp_v2 > max_samp_v)
- max_samp_v = samp_v2;
+ if (src->num_components == 3) {
+ if (samp_v1 > max_samp_v)
+ max_samp_v = samp_v1;
+ if (samp_v2 > max_samp_v)
+ max_samp_v = samp_v2;
+ }
dst->w0 = width * samp_h0 / max_samp_h;
dst->h0 = height * samp_v0 / max_samp_v;
- dst->w1 = width * samp_h1 / max_samp_h;
- dst->h1 = height * samp_v1 / max_samp_v;
+ if (src->num_components == 3) {
+ dst->w1 = width * samp_h1 / max_samp_h;
+ dst->h1 = height * samp_v1 / max_samp_v;
- dst->w2 = width * samp_h2 / max_samp_h;
- dst->h2 = height * samp_v2 / max_samp_v;
+ dst->w2 = width * samp_h2 / max_samp_h;
+ dst->h2 = height * samp_v2 / max_samp_v;
+ }
dst->samp_h0 = samp_h0;
dst->samp_v0 = samp_v0;
- dst->samp_h1 = samp_h1;
- dst->samp_v1 = samp_v1;
+ if (src->num_components == 3) {
+ dst->samp_h1 = samp_h1;
+ dst->samp_v1 = samp_v1;
- dst->samp_h2 = samp_h2;
- dst->samp_v2 = samp_v2;
+ dst->samp_h2 = samp_h2;
+ dst->samp_v2 = samp_v2;
+ }
unsigned dstride0 = (dst->w0 + DCTSIZE-1) & ~(DCTSIZE-1);
unsigned dstride1 = (dst->w1 + DCTSIZE-1) & ~(DCTSIZE-1);
hscale(npix, dst->data_y, src->w0, dst->h0, dst->w0, sstride0, dstride0, scaling_filter);
free(npix);
}
- {
- float *npix = (float*)memalign(16, sstride1 * dst->h1 * sizeof(float));
- vscale(src->data_cr, npix, sstride1, src->h1, dst->h1, sstride1, scaling_filter);
- dst->data_cr = (unsigned char *)malloc(dst->h1 * dstride1);
- hscale(npix, dst->data_cr, src->w1, dst->h1, dst->w1, sstride1, dstride1, scaling_filter);
- free(npix);
- }
- {
- float *npix = (float*)memalign(16, sstride2 * dst->h2 * sizeof(float));
- vscale(src->data_cb, npix, sstride2, src->h2, dst->h2, sstride2, scaling_filter);
- dst->data_cb = (unsigned char *)malloc(dst->h2 * dstride2);
- hscale(npix, dst->data_cb, src->w2, dst->h2, dst->w2, sstride2, dstride2, scaling_filter);
- free(npix);
+ if (src->num_components == 3) {
+ {
+ float *npix = (float*)memalign(16, sstride1 * dst->h1 * sizeof(float));
+ vscale(src->data_cr, npix, sstride1, src->h1, dst->h1, sstride1, scaling_filter);
+ dst->data_cr = (unsigned char *)malloc(dst->h1 * dstride1);
+ hscale(npix, dst->data_cr, src->w1, dst->h1, dst->w1, sstride1, dstride1, scaling_filter);
+ free(npix);
+ }
+ {
+ float *npix = (float*)memalign(16, sstride2 * dst->h2 * sizeof(float));
+ vscale(src->data_cb, npix, sstride2, src->h2, dst->h2, sstride2, scaling_filter);
+ dst->data_cb = (unsigned char *)malloc(dst->h2 * dstride2);
+ hscale(npix, dst->data_cb, src->w2, dst->h2, dst->w2, sstride2, dstride2, scaling_filter);
+ free(npix);
+ }
}
return dst;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, file);
- cinfo.input_components = 3;
+ cinfo.input_components = img->num_components;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, jpeg_quality, FALSE);
cinfo.image_width = img->width;
cinfo.image_height = img->height;
cinfo.raw_data_in = TRUE;
- jpeg_set_colorspace(&cinfo, JCS_YCbCr);
+ if (img->num_components == 3) {
+ jpeg_set_colorspace(&cinfo, JCS_YCbCr);
+ } else {
+ jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE);
+ }
cinfo.comp_info[0].h_samp_factor = img->samp_h0;
cinfo.comp_info[0].v_samp_factor = img->samp_v0;
- cinfo.comp_info[1].h_samp_factor = img->samp_h1;
- cinfo.comp_info[1].v_samp_factor = img->samp_v1;
- cinfo.comp_info[2].h_samp_factor = img->samp_h2;
- cinfo.comp_info[2].v_samp_factor = img->samp_v2;
+ if (img->num_components == 3) {
+ cinfo.comp_info[1].h_samp_factor = img->samp_h1;
+ cinfo.comp_info[1].v_samp_factor = img->samp_v1;
+ cinfo.comp_info[2].h_samp_factor = img->samp_h2;
+ cinfo.comp_info[2].v_samp_factor = img->samp_v2;
+ }
jpeg_start_compress(&cinfo, TRUE);
unsigned dstride0 = (img->w0 + DCTSIZE-1) & ~(DCTSIZE-1);
if (yline > img->h0 - 1)
yline = img->h0 - 1;
- int cbline = i + blocks*DCTSIZE*cinfo.comp_info[1].v_samp_factor;
- if (cbline > img->h1 - 1)
- cbline = img->h1 - 1;
+ y_row_ptrs[i] = img->data_y + yline * dstride0;
+
+ if (img->num_components == 3) {
+ int cbline = i + blocks*DCTSIZE*cinfo.comp_info[1].v_samp_factor;
+ if (cbline > img->h1 - 1)
+ cbline = img->h1 - 1;
- int crline = i + blocks*DCTSIZE*cinfo.comp_info[2].v_samp_factor;
- if (crline > img->h2 - 1)
- crline = img->h2 - 1;
+ int crline = i + blocks*DCTSIZE*cinfo.comp_info[2].v_samp_factor;
+ if (crline > img->h2 - 1)
+ crline = img->h2 - 1;
- y_row_ptrs[i] = img->data_y + yline * dstride0;
- cb_row_ptrs[i] = img->data_cb + cbline * dstride1;
- cr_row_ptrs[i] = img->data_cr + crline * dstride2;
+ cb_row_ptrs[i] = img->data_cb + cbline * dstride1;
+ cr_row_ptrs[i] = img->data_cr + crline * dstride2;
+ }
}
total_lines += max_lines;