/* * jpegscale.c */ #include #include #include #include /* * mmmm! magic numbers! */ #if 0 int scaling_coeffs[16][8] = { { 512, 0, 0, 0, 0, 0, 0, 0, }, { 0, -464, 0, 163, 0, -109, 0, 92, }, { 0, 209, 0, 397, 0, -177, 0, 139, }, { 0, 0, -502, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 472, 0, 0, 0, }, { 0, 35, 0, -242, 0, -363, 0, 177, }, { 0, 8, 0, -46, 0, 211, 0, 368, }, { 0, 0, 5, 0, 0, 0, -427, 0, }, { 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, -9, 0, 24, 0, -138, 0, -247, }, { 0, 0, 5, 0, 0, 0, 284, 0, }, { 0, 0, 0, 0, -192, 0, 0, 0, }, { 0, -14, 0, 99, 0, 148, 0, -72, }, { 0, -41, 0, -78, 0, 36, 0, -26, }, { 0, 0, 99, 0, 0, 0, -2, 0, }, }; int scaling_factor = 1024; #else int scaling_coeffs[16][8] = { { 1024, 0, 0, 0, 0, 0, 0, 0, }, { 0, -928, 0, 326, 0, -218, 0, 185, }, { 0, 418, 0, 794, 0, -354, 0, 279, }, { 0, 0, -1004, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 946, 0, 0, 0, }, { 0, 71, 0, -486, 0, -727, 0, 355, }, { 0, 19, 0, -83, 0, 418, 0, 737, }, { 0, 0, 0, 0, 0, 0, -851, 0, }, { 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, -13, 0, 55, 0, -279, 0, -493, }, { 0, 0, 0, 0, 0, 0, 569, 0, }, { 0, 0, 0, 0, -392, 0, 0, 0, }, { 0, -29, 0, 201, 0, 301, 0, -147, }, { 0, -83, 0, -158, 0, 70, 0, -55, }, { 0, 0, 200, 0, 0, 0, 0, 0, }, }; int scaling_factor = 2048; #endif void do_scale (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, jvirt_barray_ptr *src_coef_arrays) { JDIMENSION MCU_cols, comp_width, blk_x, blk_y; int ci, i, k, j, offset_y; JBLOCKARRAY buffer; JCOEFPTR ptr0, ptr1, ptr2; int temp[DCTSIZE]; jpeg_component_info *compptr; MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); for (ci = 0; ci < dstinfo->num_components; ci++) { compptr = dstinfo->comp_info + ci; comp_width = MCU_cols * compptr->h_samp_factor; for (blk_y = 0; blk_y < compptr->height_in_blocks; blk_y += compptr->v_samp_factor) { buffer = (*srcinfo->mem->access_virt_barray) ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { for (blk_x = 0; 2 * blk_x + 1 < comp_width; blk_x ++) { ptr0 = buffer[offset_y][blk_x]; ptr1 = buffer[offset_y][2 * blk_x]; ptr2 = buffer[offset_y][2 * blk_x + 1]; for (i = 0; i < DCTSIZE; i++) { for (k = 0; k < DCTSIZE; k++) { temp[k] = 0; for (j = 0; j < DCTSIZE; j++) { temp[k] += (ptr2[j] + ptr1[j]) * scaling_coeffs[j*2][k]; temp[k] += (ptr2[j] - ptr1[j]) * scaling_coeffs[j*2+1][k]; } } for (k = 0; k < DCTSIZE; k++) { ptr0[k] = temp[k] / scaling_factor; } ptr0 += DCTSIZE; ptr1 += DCTSIZE; ptr2 += DCTSIZE; } } } } } } int main (int argc, char **argv) { struct jpeg_decompress_struct srcinfo; struct jpeg_compress_struct dstinfo; struct jpeg_error_mgr jsrcerr, jdsterr; jvirt_barray_ptr * src_coef_arrays; jvirt_barray_ptr * dst_coef_arrays; srcinfo.err = jpeg_std_error (&jsrcerr); jpeg_create_decompress (&srcinfo); dstinfo.err = jpeg_std_error (&jdsterr); jpeg_create_compress (&dstinfo); /* Specify data source for decompression */ jpeg_stdio_src (&srcinfo, stdin); /* Read file header */ jpeg_read_header (&srcinfo, TRUE); /* Read source file as DCT coefficients */ src_coef_arrays = jpeg_read_coefficients (&srcinfo); /* Initialize destination compression parameters from source values */ jpeg_copy_critical_parameters (&srcinfo, &dstinfo); dstinfo.num_components = 1; dst_coef_arrays = src_coef_arrays; /* Specify data destination for compression */ jpeg_stdio_dest (&dstinfo, stdout); /* Start compressor (note no image data is actually written here) */ jpeg_write_coefficients (&dstinfo, dst_coef_arrays); /* Execute image transformation, if any */ do_scale (&srcinfo, &dstinfo, src_coef_arrays); /* Finish compression and release memory */ jpeg_finish_compress (&dstinfo); jpeg_destroy_compress (&dstinfo); jpeg_finish_decompress (&srcinfo); jpeg_destroy_decompress (&srcinfo); /* All done. */ exit (jsrcerr.num_warnings + jdsterr.num_warnings ? -1 : 0); return 0; }