Encoding image data to JPEG is straightforward: use libjpeg. However, if you care about runtime performance, things get a bit more complicated... Here are some observations on the task on a ARM Cortex-A8 CPU.
dct_method = JDCT_IFAST
.
# time ./cjpeg -dct int -q 70 test.ppm > /tmp/test.jpg real 0m 1.70s # time ./cjpeg -dct fast -q 70 test.ppm > /tmp/test.jpg real 0m 1.04s
in_color_space = JCS_YCbCr
to avoid extra effort.
raw_data_in = TRUE
is used. The raw interface requires rearranging input data, however.
-O2
).
struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); cinfo.image_width = w; cinfo.image_height = h; cinfo.input_components = 3; cinfo.in_color_space = JCS_YCbCr; // input color space jpeg_mem_dest(&cinfo, &outbuf, outbuf_size); jpeg_set_defaults(&cinfo); cinfo.dct_method = JDCT_IFAST; // DCT method // set up subsampling cinfo.raw_data_in = TRUE; cinfo.comp_info[0].h_samp_factor = 2; cinfo.comp_info[0].v_samp_factor = 2; cinfo.comp_info[1].h_samp_factor = 1; cinfo.comp_info[1].v_samp_factor = 1; cinfo.comp_info[2].h_samp_factor = 1; cinfo.comp_info[2].v_samp_factor = 1; jpeg_set_quality(&cinfo, 70, TRUE); jpeg_start_compress(&cinfo, TRUE); // allocate input data buffer JSAMPIMAGE data = malloc(sizeof(JSAMPARRAY) * cinfo.input_components); data[0] = malloc(sizeof(JSAMPROW) * (16 + 8 + 8)); data[1] = data[0] + 16; data[2] = data[0] + 16 + 8; // Y component data[0][0] = malloc(sizeof(JSAMPLE) * cinfo.image_width * 16); for (unsigned i = 1; i < 16; i++) data[0][i] = data[0][i-1] + cinfo.image_width; // U component data[1][0] = malloc(sizeof(JSAMPLE) * cinfo.image_width * 8 / 2); for (unsigned i = 1; i < 8; i++) data[1][i] = data[1][i-1] + cinfo.image_width / 2; // V component data[2][0] = malloc(sizeof(JSAMPLE) * cinfo.image_width * 8 / 2); for (unsigned i = 1; i < 8; i++) data[2][i] = data[2][i-1] + cinfo.image_width / 2; JSAMPLE *in = inbuf; for (unsigned i = 0; i < cinfo.image_height; i += 16) { JSAMPLE *yp = data[0][0], *up = data[1][0], *vp = data[2][0]; for (unsigned j = 0; j < 16; j += 2) { for (unsigned k = 0; k < cinfo.image_width * 2; k += 4) { *up++ = *in++; // assume UYVY *yp++ = *in++; *vp++ = *in++; *yp++ = *in++; } for (unsigned k = 0; k < cinfo.image_width * 2; k += 4) { in++; // subsample by dropping chroma data on odd lines *yp++ = *in++; in++; *yp++ = *in++; } } jpeg_write_raw_data(&cinfo, data, 16); } free(data[0][0]); free(data[1][0]); free(data[2][0]); free(data[0]); free(data); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo);
posted at: 15:19 | path: /programming | permanent link