7 qscale_img *qscale_load_jpeg(const char *filename)
9 FILE *file = fopen(filename, "rb");
15 img = qscale_load_jpeg_from_stdio(file);
21 qscale_img *qscale_load_jpeg_from_stdio(FILE *file)
23 qscale_img *img = (qscale_img *)malloc(sizeof(qscale_img));
28 img->data_y = img->data_cb = img->data_cr = NULL;
30 /* FIXME: Better error handling here (ie., return NULL). */
31 struct jpeg_decompress_struct dinfo;
32 struct jpeg_error_mgr jerr;
33 dinfo.err = jpeg_std_error(&jerr);
34 jpeg_create_decompress(&dinfo);
35 jpeg_stdio_src(&dinfo, stdin);
36 jpeg_read_header(&dinfo, TRUE);
37 dinfo.raw_data_out = TRUE;
38 jpeg_start_decompress(&dinfo);
40 /* We do not handle anything but YCbCr images (yet?). */
41 if (dinfo.num_components != 3) {
46 img->width = dinfo.image_width;
47 img->height = dinfo.image_height;
49 img->w0 = dinfo.image_width * dinfo.comp_info[0].h_samp_factor / dinfo.max_h_samp_factor;
50 img->h0 = dinfo.image_height * dinfo.comp_info[0].v_samp_factor / dinfo.max_v_samp_factor;
52 img->w1 = dinfo.image_width * dinfo.comp_info[1].h_samp_factor / dinfo.max_h_samp_factor;
53 img->h1 = dinfo.image_height * dinfo.comp_info[1].v_samp_factor / dinfo.max_v_samp_factor;
55 img->w2 = dinfo.image_width * dinfo.comp_info[2].h_samp_factor / dinfo.max_h_samp_factor;
56 img->h2 = dinfo.image_height * dinfo.comp_info[2].v_samp_factor / dinfo.max_v_samp_factor;
58 img->data_y = (JSAMPLE*)memalign(16, dinfo.comp_info[0].height_in_blocks * dinfo.comp_info[0].width_in_blocks * DCTSIZE * DCTSIZE);
59 img->data_cb = (JSAMPLE*)memalign(16, dinfo.comp_info[1].height_in_blocks * dinfo.comp_info[1].width_in_blocks * DCTSIZE * DCTSIZE);
60 img->data_cr = (JSAMPLE*)memalign(16, dinfo.comp_info[2].height_in_blocks * dinfo.comp_info[2].width_in_blocks * DCTSIZE * DCTSIZE);
62 if (img->data_y == NULL || img->data_cb == NULL || img->data_cr == NULL) {
67 int total_lines = 0, blocks = 0;
68 while (total_lines < dinfo.comp_info[0].height_in_blocks * DCTSIZE) {
69 unsigned max_lines = dinfo.max_v_samp_factor * DCTSIZE;
71 JSAMPROW y_row_ptrs[max_lines];
72 JSAMPROW cb_row_ptrs[max_lines];
73 JSAMPROW cr_row_ptrs[max_lines];
74 JSAMPROW* ptrs[] = { y_row_ptrs, cb_row_ptrs, cr_row_ptrs };
77 for (i = 0; i < max_lines; ++i) {
78 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;
79 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;
80 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;
83 total_lines += max_lines;
86 if (jpeg_read_raw_data(&dinfo, ptrs, max_lines) == 0)
90 jpeg_destroy_decompress(&dinfo);
94 void qscale_destroy(qscale_img *img)