+ unsigned nominal_w = atoi(argv[1]);
+ unsigned nominal_h = atoi(argv[2]);
+
+ unsigned samp_h0 = 2, samp_v0 = 2;
+ unsigned samp_h1 = 1, samp_v1 = 1;
+ unsigned samp_h2 = 1, samp_v2 = 1;
+ unsigned max_samp_h = 2, max_samp_v = 2;
+
+ unsigned nw0 = nominal_w * samp_h0 / max_samp_h, nh0 = nominal_h * samp_v0 / max_samp_v;
+ unsigned nw1 = nominal_w * samp_h1 / max_samp_h, nh1 = nominal_h * samp_v1 / max_samp_v;
+ unsigned nw2 = nominal_w * samp_h2 / max_samp_h, nh2 = nominal_h * samp_v2 / max_samp_v;
+
+ unsigned stride0 = (nw0 + DCTSIZE-1) & ~(DCTSIZE-1);
+ unsigned stride1 = (nw1 + DCTSIZE-1) & ~(DCTSIZE-1);
+ unsigned stride2 = (nw2 + DCTSIZE-1) & ~(DCTSIZE-1);
+
+ struct jpeg_decompress_struct dinfo;
+ struct jpeg_error_mgr jerr;
+ dinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&dinfo);
+ jpeg_stdio_src(&dinfo, stdin);
+ jpeg_read_header(&dinfo, TRUE);
+ dinfo.raw_data_out = TRUE;
+ jpeg_start_decompress(&dinfo);
+
+ fprintf(stderr, "Scaling using Lanczos filter:\n");
+ fprintf(stderr, " Y component: %ux%u -> %ux%u\n", dinfo.comp_info[0].width_in_blocks * DCTSIZE, dinfo.comp_info[0].height_in_blocks * DCTSIZE, nw0, nh0);
+ fprintf(stderr, " Cb component: %ux%u -> %ux%u\n", dinfo.comp_info[1].width_in_blocks * DCTSIZE, dinfo.comp_info[1].height_in_blocks * DCTSIZE, nw1, nh1);
+ fprintf(stderr, " Cr component: %ux%u -> %ux%u\n", dinfo.comp_info[2].width_in_blocks * DCTSIZE, dinfo.comp_info[2].height_in_blocks * DCTSIZE, nw2, nh2);
+
+ float *npix_y = (float *)malloc((dinfo.comp_info[0].height_in_blocks + dinfo.comp_info[0].v_samp_factor - 1) * DCTSIZE * stride0 * sizeof(float));
+ float *npix_cb = (float *)malloc((dinfo.comp_info[1].height_in_blocks + dinfo.comp_info[1].v_samp_factor - 1) * DCTSIZE * stride1 * sizeof(float));
+ float *npix_cr = (float *)malloc((dinfo.comp_info[2].height_in_blocks + dinfo.comp_info[2].v_samp_factor - 1) * DCTSIZE * stride2 * sizeof(float));
+ JSAMPLE *data_y = (unsigned char *)malloc(nh0 * stride0);
+ JSAMPLE *data_cb = (unsigned char *)malloc(nh1 * stride1);
+ JSAMPLE *data_cr = (unsigned char *)malloc(nh2 * stride2);
+
+ struct filter filt0, filt1, filt2;
+
+ hscale_calc_filter(&filt0,
+ /* w= */ dinfo.image_width * dinfo.comp_info[0].h_samp_factor / dinfo.max_h_samp_factor,
+ /* h= */ dinfo.comp_info[0].v_samp_factor * DCTSIZE,
+ /* nw= */ nw0
+ );
+ hscale_calc_filter(&filt1,
+ /* w= */ dinfo.image_width * dinfo.comp_info[1].h_samp_factor / dinfo.max_h_samp_factor,
+ /* h= */ dinfo.comp_info[1].v_samp_factor * DCTSIZE,
+ /* nw= */ nw1
+ );
+ hscale_calc_filter(&filt2,
+ /* w= */ dinfo.image_width * dinfo.comp_info[2].h_samp_factor / dinfo.max_h_samp_factor,
+ /* h= */ dinfo.comp_info[2].v_samp_factor * DCTSIZE,
+ /* nw= */ nw2
+ );
+
+ 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;
+ JSAMPLE tmp_y [(dinfo.comp_info[0].width_in_blocks * DCTSIZE) * (DCTSIZE * dinfo.comp_info[0].v_samp_factor)];
+ JSAMPLE tmp_cb[(dinfo.comp_info[1].width_in_blocks * DCTSIZE) * (DCTSIZE * dinfo.comp_info[1].v_samp_factor)];
+ JSAMPLE tmp_cr[(dinfo.comp_info[2].width_in_blocks * DCTSIZE) * (DCTSIZE * dinfo.comp_info[2].v_samp_factor)];
+
+ JSAMPROW y_row_ptrs[max_lines];
+ JSAMPROW cb_row_ptrs[max_lines];
+ JSAMPROW cr_row_ptrs[max_lines];
+ JSAMPROW* ptrs[] = { y_row_ptrs, cb_row_ptrs, cr_row_ptrs };
+ int i;
+
+ for (i = 0; i < max_lines; ++i) {
+ y_row_ptrs[i] = tmp_y + i * dinfo.comp_info[0].width_in_blocks * DCTSIZE;
+ cb_row_ptrs[i] = tmp_cb + i * dinfo.comp_info[1].width_in_blocks * DCTSIZE;
+ cr_row_ptrs[i] = tmp_cr + i * dinfo.comp_info[2].width_in_blocks * DCTSIZE;
+ }
+
+ int lines = jpeg_read_raw_data(&dinfo, ptrs, max_lines);
+ if (lines == 0)
+ break;
+
+ hscale(/* filter= */ &filt0,
+ /* from= */ tmp_y,
+ /* to= */ npix_y + blocks * DCTSIZE * dinfo.comp_info[0].v_samp_factor * stride0,
+ /* w= */ dinfo.image_width * dinfo.comp_info[0].h_samp_factor / dinfo.max_h_samp_factor,
+ /* h= */ dinfo.comp_info[0].v_samp_factor * DCTSIZE,
+ /* nw= */ nw0,
+ /* sstride= */ dinfo.comp_info[0].width_in_blocks * DCTSIZE,
+ /* dstride= */ stride0);
+
+ hscale(/* filter= */ &filt1,
+ /* from= */ tmp_cb,
+ /* to= */ npix_cb + blocks * DCTSIZE * dinfo.comp_info[1].v_samp_factor * stride1,
+ /* w= */ dinfo.image_width * dinfo.comp_info[1].h_samp_factor / dinfo.max_h_samp_factor,
+ /* h= */ dinfo.comp_info[1].v_samp_factor * DCTSIZE,
+ /* nw= */ nw1,
+ /* sstride= */ dinfo.comp_info[1].width_in_blocks * DCTSIZE,
+ /* dstride= */ stride1);
+
+ hscale(/* filter= */ &filt2,
+ /* from= */ tmp_cr,
+ /* to= */ npix_cr + blocks * DCTSIZE * dinfo.comp_info[2].v_samp_factor * stride2,
+ /* w= */ dinfo.image_width * dinfo.comp_info[2].h_samp_factor / dinfo.max_h_samp_factor,
+ /* h= */ dinfo.comp_info[2].v_samp_factor * DCTSIZE,
+ /* nw= */ nw2,
+ /* sstride= */ dinfo.comp_info[2].width_in_blocks * DCTSIZE,
+ /* dstride= */ stride2);
+
+ total_lines += max_lines;
+ ++blocks;