1 /*
2  * rdjpeg.c
3  *
4  * Copyright (C) 1991-1996, Thomas G. Lane.
5  * mozjpeg Modifications:
6  * Copyright (C) 2014, Mozilla Corporation.
7  * This file is part of the Independent JPEG Group's software.
8  * For conditions of distribution and use, see the accompanying README file.
9  *
10  */
11 
12 #include "cdjpeg.h"             /* Common decls for cjpeg/djpeg applications */
13 
14 #if JPEG_RAW_READER
15 #define NUM_ROWS 32
16 #endif
17 
18 /* Private version of data source object */
19 
20 typedef struct _jpeg_source_struct * jpeg_source_ptr;
21 
22 typedef struct _jpeg_source_struct {
23   struct cjpeg_source_struct pub; /* public fields */
24 
25   j_compress_ptr cinfo;         /* back link saves passing separate parm */
26 
27   struct jpeg_decompress_struct dinfo;
28   struct jpeg_error_mgr jerr;
29 } jpeg_source_struct;
30 
31 
32 
33 METHODDEF(JDIMENSION)
get_rows(j_compress_ptr cinfo,cjpeg_source_ptr sinfo)34 get_rows (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
35 {
36   jpeg_source_ptr source = (jpeg_source_ptr) sinfo;
37 
38 #if !JPEG_RAW_READER
39   return jpeg_read_scanlines(&source->dinfo, source->pub.buffer, source->pub.buffer_height);
40 #else
41   jpeg_read_raw_data(&source->dinfo, source->pub.plane_pointer, 8*cinfo->max_v_samp_factor);
42 
43   return 8*cinfo->max_v_samp_factor;
44 #endif
45 }
46 
47 
48 /*
49  * Read the file header; return image size and component count.
50  */
51 
52 METHODDEF(void)
start_input_jpeg(j_compress_ptr cinfo,cjpeg_source_ptr sinfo)53 start_input_jpeg (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
54 {
55 #if JPEG_RAW_READER
56   int i;
57 #endif
58   int m;
59   jpeg_source_ptr source = (jpeg_source_ptr) sinfo;
60 
61   source->dinfo.err = jpeg_std_error(&source->jerr);
62   jpeg_create_decompress(&source->dinfo);
63   jpeg_stdio_src(&source->dinfo, source->pub.input_file);
64 
65   jpeg_save_markers(&source->dinfo, JPEG_COM, 0xFFFF);
66 
67   for (m = 0; m < 16; m++)
68     jpeg_save_markers(&source->dinfo, JPEG_APP0 + m, 0xFFFF);
69 
70   jpeg_read_header(&source->dinfo, TRUE);
71 
72   source->pub.marker_list = source->dinfo.marker_list;
73 
74 #if !JPEG_RAW_READER
75   source->dinfo.raw_data_out = FALSE;
76 
77   jpeg_start_decompress(&source->dinfo);
78 
79   cinfo->in_color_space = source->dinfo.out_color_space;
80   cinfo->input_components = source->dinfo.output_components;
81   cinfo->data_precision = source->dinfo.data_precision;
82   cinfo->image_width = source->dinfo.image_width;
83   cinfo->image_height = source->dinfo.image_height;
84 
85   cinfo->raw_data_in = FALSE;
86 
87   source->pub.buffer = (*cinfo->mem->alloc_sarray)
88   ((j_common_ptr) cinfo, JPOOL_IMAGE,
89    (JDIMENSION) (cinfo->image_width * cinfo->input_components), (JDIMENSION) 1);
90   source->pub.buffer_height = 1;
91 #else
92   source->dinfo.raw_data_out = TRUE;
93   source->dinfo.do_fancy_upsampling = FALSE;
94 
95   jpeg_start_decompress(&source->dinfo);
96 
97   cinfo->in_color_space = source->dinfo.out_color_space;
98   cinfo->input_components = source->dinfo.output_components;
99   cinfo->data_precision = source->dinfo.data_precision;
100   cinfo->image_width = source->dinfo.image_width;
101   cinfo->image_height = source->dinfo.image_height;
102 
103   jpeg_set_colorspace(cinfo, source->dinfo.jpeg_color_space);
104 
105   cinfo->max_v_samp_factor = source->dinfo.max_v_samp_factor;
106   cinfo->max_h_samp_factor = source->dinfo.max_h_samp_factor;
107 
108   cinfo->raw_data_in = TRUE;
109 #if JPEG_LIB_VERSION >= 70
110   cinfo->do_fancy_upsampling = FALSE;
111 #endif
112 
113   for (i = 0; i < cinfo->input_components; i++) {
114     cinfo->comp_info[i].h_samp_factor = source->dinfo.comp_info[i].h_samp_factor;
115     cinfo->comp_info[i].v_samp_factor = source->dinfo.comp_info[i].v_samp_factor;
116 
117     source->pub.plane_pointer[i] =  (*cinfo->mem->alloc_sarray)
118     ((j_common_ptr) cinfo, JPOOL_IMAGE,
119      (JDIMENSION) cinfo->image_width, (JDIMENSION) NUM_ROWS);
120   }
121 #endif
122 
123   source->pub.get_pixel_rows = get_rows;
124 }
125 
126 
127 /*
128  * Finish up at the end of the file.
129  */
130 
131 METHODDEF(void)
finish_input_jpeg(j_compress_ptr cinfo,cjpeg_source_ptr sinfo)132 finish_input_jpeg (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
133 {
134   jpeg_source_ptr source = (jpeg_source_ptr) sinfo;
135 
136   jpeg_finish_decompress(&source->dinfo);
137   jpeg_destroy_decompress(&source->dinfo);
138 }
139 
140 
141 /*
142  * The module selection routine for JPEG format input.
143  */
144 
145 GLOBAL(cjpeg_source_ptr)
jinit_read_jpeg(j_compress_ptr cinfo)146 jinit_read_jpeg (j_compress_ptr cinfo)
147 {
148   jpeg_source_ptr source;
149 
150   /* Create module interface object */
151   source = (jpeg_source_ptr)
152       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
153                                   sizeof(jpeg_source_struct));
154   source->cinfo = cinfo;        /* make back link for subroutines */
155   /* Fill in method ptrs, except get_pixel_rows which start_input sets */
156   source->pub.start_input = start_input_jpeg;
157   source->pub.finish_input = finish_input_jpeg;
158 
159   return (cjpeg_source_ptr) source;
160 }
161