]> git.sesse.net Git - qscale/commitdiff
Move JPEG loading into libqscale.
authorsgunderson@bigfoot.com <>
Thu, 29 May 2008 05:09:25 +0000 (22:09 -0700)
committersgunderson@bigfoot.com <>
Thu, 29 May 2008 05:09:25 +0000 (22:09 -0700)
Makefile
libqscale.c [new file with mode: 0644]
qscale.c

index df52768fdf6a3d0963df512fe4e1c78bd1ab91f2..37a0dd84cb82ba2fff2d052cc418903e22307b9b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,10 @@
 CC=gcc
-OBJS=qscale.o
+OBJS=qscale.o libqscale.o
 
 CFLAGS=-Wall -O2 -msse
 LDFLAGS=-lm -ljpeg
 
-qscale: qscale.o
+qscale: qscale.o libqscale.o
 
 clean:
        $(RM) qscale $(OBJS)
diff --git a/libqscale.c b/libqscale.c
new file mode 100644 (file)
index 0000000..b744a9b
--- /dev/null
@@ -0,0 +1,100 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+
+#include "libqscale.h"
+
+qscale_img *qscale_load_jpeg(const char *filename)
+{
+       FILE *file = fopen(filename, "rb");
+       qscale_img *img;
+       if (file == NULL) {
+               return NULL;
+       }
+
+       img = qscale_load_jpeg_from_stdio(file);
+
+       fclose(file);
+       return img;
+}
+
+qscale_img *qscale_load_jpeg_from_stdio(FILE *file)
+{
+       qscale_img *img = (qscale_img *)malloc(sizeof(qscale_img));
+       if (img == NULL) {
+               return NULL;
+       }
+
+       img->data_y = img->data_cb = img->data_cr = NULL;
+
+       /* FIXME: Better error handling here (ie., return NULL). */
+       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);
+       
+       /* We do not handle anything but YCbCr images (yet?). */
+       if (dinfo.num_components != 3) {
+               qscale_destroy(img);
+               return NULL;
+       }
+
+       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;
+
+       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->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) {
+               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;
+
+                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]  = 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;
+                }
+
+                total_lines += max_lines;
+                ++blocks;
+
+                if (jpeg_read_raw_data(&dinfo, ptrs, max_lines) == 0)
+                        break;
+        }
+
+       jpeg_destroy_decompress(&dinfo);
+       return img;
+}
+
+void qscale_destroy(qscale_img *img)
+{
+       free(img->data_y);
+       free(img->data_cb);
+       free(img->data_cr);
+       free(img);
+}
index d89c8b9463d9a34cc367a22f72f4e4b9f75a7b7d..440f9dee287328cb77e7761a5ac7a516d5c7e903 100644 (file)
--- a/qscale.c
+++ b/qscale.c
 #include <string.h>
 #include <stdlib.h>
 #include "jpeglib.h"
+#include "libqscale.h"
 
 /* The number of pixels to process at a time when scaling vertically. */
 #define CACHE_LINE_FACTOR 16
 
 /* Whether to use SSE for horizontal scaling or not (requires SSE3). */
-#define USE_HORIZONTAL_SSE 1
+#define USE_HORIZONTAL_SSE 0
 
 /* Whether to use SSE for vertical scaling or not (requires only SSE1). */
-#define USE_VERTICAL_SSE 1
+#define USE_VERTICAL_SSE 0
 
 #if USE_VERTICAL_SSE
 #undef CACHE_LINE_FACTOR
@@ -403,85 +404,41 @@ int main(int argc, char **argv)
        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);
+       unsigned dstride0 = (nw0 + DCTSIZE-1) & ~(DCTSIZE-1);
+       unsigned dstride1 = (nw1 + DCTSIZE-1) & ~(DCTSIZE-1);
+       unsigned dstride2 = (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);
-
-       unsigned w0 = dinfo.image_width * dinfo.comp_info[0].h_samp_factor / dinfo.max_h_samp_factor;
-       unsigned h0 = dinfo.image_height * dinfo.comp_info[0].v_samp_factor / dinfo.max_v_samp_factor;
-
-       unsigned w1 = dinfo.image_width * dinfo.comp_info[1].h_samp_factor / dinfo.max_h_samp_factor;
-       unsigned h1 = dinfo.image_height * dinfo.comp_info[1].v_samp_factor / dinfo.max_v_samp_factor;
-
-       unsigned w2 = dinfo.image_width * dinfo.comp_info[2].h_samp_factor / dinfo.max_h_samp_factor;
-       unsigned h2 = dinfo.image_height * dinfo.comp_info[2].v_samp_factor / dinfo.max_v_samp_factor;
-
-       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);
-
-       JSAMPLE *data_y  = (JSAMPLE*)memalign(16, dinfo.comp_info[0].height_in_blocks * dinfo.comp_info[0].width_in_blocks * DCTSIZE * DCTSIZE);
-       JSAMPLE *data_cb = (JSAMPLE*)memalign(16, dinfo.comp_info[1].height_in_blocks * dinfo.comp_info[1].width_in_blocks * DCTSIZE * DCTSIZE);
-       JSAMPLE *data_cr = (JSAMPLE*)memalign(16, dinfo.comp_info[2].height_in_blocks * dinfo.comp_info[2].width_in_blocks * DCTSIZE * DCTSIZE);
+       qscale_img *img = qscale_load_jpeg_from_stdio(stdin);
+       unsigned sstride0 = (img->w0 + DCTSIZE-1) & ~(DCTSIZE-1);
+       unsigned sstride1 = (img->w1 + DCTSIZE-1) & ~(DCTSIZE-1);
+       unsigned sstride2 = (img->w2 + DCTSIZE-1) & ~(DCTSIZE-1);
+       
        JSAMPLE *data_ny, *data_ncb, *data_ncr;
 
-       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;
-
-               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]  = data_y  + (i+blocks*DCTSIZE*dinfo.comp_info[0].v_samp_factor) * dinfo.comp_info[0].width_in_blocks * DCTSIZE;
-                       cb_row_ptrs[i] = data_cb + (i+blocks*DCTSIZE*dinfo.comp_info[1].v_samp_factor) * dinfo.comp_info[1].width_in_blocks * DCTSIZE;
-                       cr_row_ptrs[i] = data_cr + (i+blocks*DCTSIZE*dinfo.comp_info[2].v_samp_factor) * dinfo.comp_info[2].width_in_blocks * DCTSIZE;
-               }
-               
-               total_lines += max_lines;
-               ++blocks;
-
-               if (jpeg_read_raw_data(&dinfo, ptrs, max_lines) == 0)
-                       break;
-       }
-
        {
-               float *npix = (float*)memalign(16, dinfo.comp_info[0].width_in_blocks * DCTSIZE * nh0 * sizeof(float)); 
-               vscale(data_y, npix, dinfo.comp_info[0].width_in_blocks * DCTSIZE, h0, nh0, dinfo.comp_info[0].width_in_blocks * DCTSIZE);
-               data_ny = (unsigned char *)malloc(nh0 * stride0);
-               hscale(npix, data_ny, w0, nh0, nw0, dinfo.comp_info[0].width_in_blocks * DCTSIZE, stride0);
+               float *npix = (float*)memalign(16, sstride0 * nh0 * sizeof(float));
+               vscale(img->data_y, npix, sstride0, img->h0, nh0, sstride0);
+               data_ny = (unsigned char *)malloc(nh0 * dstride0);
+               hscale(npix, data_ny, img->w0, nh0, nw0, sstride0, dstride0);
                free(npix);
        }
        {
-               float *npix = (float*)memalign(16, dinfo.comp_info[1].width_in_blocks * DCTSIZE * nh1 * sizeof(float)); 
-               vscale(data_cr, npix, dinfo.comp_info[1].width_in_blocks * DCTSIZE, h1, nh1, dinfo.comp_info[1].width_in_blocks * DCTSIZE);
-               data_ncr = (unsigned char *)malloc(nh1 * stride1);
-               hscale(npix, data_ncr, w1, nh1, nw1, dinfo.comp_info[1].width_in_blocks * DCTSIZE, stride1);
+               float *npix = (float*)memalign(16, sstride1 * nh1 * sizeof(float));     
+               vscale(img->data_cr, npix, sstride1, img->h1, nh1, sstride1);
+               data_ncr = (unsigned char *)malloc(nh1 * dstride1);
+               hscale(npix, data_ncr, img->w1, nh1, nw1, sstride1, dstride1);
                free(npix);
        }
        {
-               float *npix = (float*)memalign(16, dinfo.comp_info[2].width_in_blocks * DCTSIZE * nh2 * sizeof(float)); 
-               vscale(data_cb, npix, dinfo.comp_info[2].width_in_blocks * DCTSIZE, h2, nh2, dinfo.comp_info[2].width_in_blocks * DCTSIZE);
-               data_ncb = (unsigned char *)malloc(nh2 * stride2);
-               hscale(npix, data_ncb, w2, nh2, nw2, dinfo.comp_info[2].width_in_blocks * DCTSIZE, stride2);
+               float *npix = (float*)memalign(16, sstride2 * nh2 * sizeof(float));     
+               vscale(img->data_cb, npix, sstride2, img->h2, nh2, sstride2);
+               data_ncb = (unsigned char *)malloc(nh2 * dstride2);
+               hscale(npix, data_ncb, img->w2, nh2, nw2, sstride2, dstride2);
                free(npix);
        }
-       jpeg_destroy_decompress(&dinfo);
        
        struct jpeg_compress_struct cinfo;
+       struct jpeg_error_mgr jerr;
        cinfo.err = jpeg_std_error(&jerr);
        jpeg_create_compress(&cinfo);
        jpeg_stdio_dest(&cinfo, stdout);
@@ -500,8 +457,8 @@ int main(int argc, char **argv)
        cinfo.comp_info[2].v_samp_factor = samp_v2;
        jpeg_start_compress(&cinfo, TRUE);
 
-       total_lines = 0;
-       blocks = 0;
+       int total_lines = 0;
+       int blocks = 0;
        while (total_lines < cinfo.comp_info[0].height_in_blocks * DCTSIZE) {
                unsigned max_lines = cinfo.max_v_samp_factor * DCTSIZE;
 
@@ -525,9 +482,9 @@ int main(int argc, char **argv)
                        if (crline > nh2 - 1)
                                crline = nh2 - 1;
 
-                       y_row_ptrs[i]  = data_ny  + yline * stride0;
-                       cb_row_ptrs[i] = data_ncb + cbline * stride1;
-                       cr_row_ptrs[i] = data_ncr + crline * stride2;
+                       y_row_ptrs[i]  = data_ny  + yline * dstride0;
+                       cb_row_ptrs[i] = data_ncb + cbline * dstride1;
+                       cr_row_ptrs[i] = data_ncr + crline * dstride2;
                }
                
                total_lines += max_lines;
@@ -538,6 +495,8 @@ int main(int argc, char **argv)
        jpeg_finish_compress(&cinfo);
        jpeg_destroy_compress(&cinfo);
 
+       qscale_destroy(img);
+
        return 0;
 }