1 /*
2 * wjfif.c --
3 *
4 * FIXME: This file needs a description here.
5 *
6 * Copyright (c) 1996-2002 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * A. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * B. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * C. Neither the names of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <stdio.h>
35 #include <fcntl.h>
36
37 #ifdef notdef
38 #include "JVplayfile.h"
39 #endif
40 #include "jfif.h"
41
42 /* This factor relates the jvideo quantization factor to the one */
43 /* used for the jfif file. 100 seems about right */
44 #define QUANTIZE_FACTOR 100
45
46 /* These defines are values we use by convention */
47 /* Components */
48 #define IdY 1
49 #define IdCb 2
50 #define IdCr 3
51 /* Table frequency bits */
52 #define tabDC 0
53 #define tabAC 1
54 /* Table colour types */
55 #define tabLUM 0
56 #define tabCRM 1
57
58 #define emitByte(ci, b) ((*((ci)->emit_byte))((ci->userInfo), (b)))
59
60 void wrbyte(wfd, b)
61 int wfd;
62 int b;
63 {
64 char c = b;
65 write(wfd, &c, 1);
66 }
67
68 void emit_marker (cInfo *cinfo, JPEG_MARKER mark)
69 /* Emit a marker code */
70 {
71 emitByte(cinfo, 0xFF);
72 emitByte(cinfo, mark);
73 }
74
75 void emit_2bytes (cInfo *cinfo, int value)
76 /* Emit a 2-byte integer; these are always MSB first in JPEG files */
77 {
78 emitByte(cinfo, (value >> 8) & 0xFF);
79 emitByte(cinfo, value & 0xFF);
80 }
81
82 /* Output the huffman tables - using baseline DCT, so restrict to 8 bits */
83
84 void emit_dqts(cinfo, qFactor)
85 cInfo *cinfo;
86 int qFactor;
87 {
88 int i;
89 int nomsg = 1;
90
91 emit_marker(cinfo, M_DQT);
92 emit_2bytes(cinfo, DCTSIZE2 + 1 + 2); /* Size of table */
93 emitByte(cinfo, tabLUM); /* luminance table */
94 for(i = 0; i < DCTSIZE2; i++)
95 {
96 int val = (std_luminance_quant_tbl[i] * qFactor)/QUANTIZE_FACTOR;
97 if (val < 2) val = 2;
98 if (val > 255)
99 {
100 if (nomsg)
101 {
102 fprintf(stderr, "JFIF generation: qFactor %d\n", qFactor);
103 fprintf(stderr,
104 "Luminance quantisation values > 8-bit truncated to 255\n");
105 nomsg = 0;
106 }
107 val = 255;
108 }
109 emitByte(cinfo, val);
110 }
111
112 emit_marker(cinfo, M_DQT);
113 emit_2bytes(cinfo, DCTSIZE2 + 1 + 2); /* Size of table */
114 emitByte(cinfo, tabCRM); /* chrominance */
115 for(i = 0; i < DCTSIZE2; i++)
116 {
117 int val = (std_chrominance_quant_tbl[i] * qFactor)/QUANTIZE_FACTOR;
118 if (val < 2) val = 2;
119 if (val > 255)
120 {
121 if (nomsg)
122 {
123 fprintf(stderr, "JFIF generation: qFactor %d\n", qFactor);
124 fprintf(stderr,
125 "Chrominance uantisation values > 8-bit truncated to 255\n");
126 nomsg = 0;
127 }
128 val = 255;
129 }
130 emitByte(cinfo, val);
131 }
132 }
133
134 /* Output a single Huffman table */
135 void emit_dht (cinfo, index, bits, vals)
136 cInfo *cinfo;
137 int index;
138 unsigned char *bits;
139 unsigned char *vals;
140 {
141 int length, i;
142
143 emit_marker(cinfo, M_DHT);
144
145 /* Count the number of values by adding the numbers with each bit code */
146 length = 0;
147 for (i = 1; i <= 16; i++)
148 length += bits[i];
149
150 emit_2bytes(cinfo, length + 2 + 1 + 16); /* Length */
151 emitByte(cinfo, index); /* Id code for table */
152
153 for (i = 1; i <= 16; i++)
154 emitByte(cinfo, bits[i]); /* The bit division */
155 for (i = 0; i < length; i++) /* the actual values */
156 emitByte(cinfo, vals[i]);
157 }
158
159 /* Output all the Huffman tables */
160 /* The index has bit 4 == 1 for an AC table and == 0 for DC */
161 /* Index low 4 bits have id, we use 0 for Y and 1 for the colours */
162 void emit_dhts(cinfo)
163 cInfo *cinfo;
164 {
165 emit_dht(cinfo, (tabDC<<4) | tabLUM, dc_luminance_bits, dc_luminance_val);
166 emit_dht(cinfo, (tabAC<<4) | tabLUM, ac_luminance_bits, ac_luminance_val);
167 emit_dht(cinfo, (tabDC<<4) | tabCRM, dc_chrominance_bits,dc_chrominance_val);
168 emit_dht(cinfo, (tabAC<<4) | tabCRM, ac_chrominance_bits,ac_chrominance_val);
169 }
170
171 /* Output a frame marker and details */
172 void emit_sof (cInfo *cinfo, JPEG_MARKER code)
173 {
174 int i;
175
176 emit_marker(cinfo, code);
177 emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
178
179 if (cinfo->image_height > 65535L || cinfo->image_width > 65535L)
180 {
181 printf("Maximum image dimension for JFIF is 65535 pixels");
182 exit(1);
183 }
184
185 emitByte(cinfo, cinfo->data_precision);
186 emit_2bytes(cinfo, (int) cinfo->image_height);
187 emit_2bytes(cinfo, (int) cinfo->image_width);
188 emitByte(cinfo, cinfo->num_components);
189
190 for (i = 0; i < cinfo->num_components; i++) {
191 emitByte(cinfo, cinfo->comp_info[i].component_id);
192 emitByte(cinfo, (cinfo->comp_info[i].h_samp_factor << 4)
193 + cinfo->comp_info[i].v_samp_factor);
194 emitByte(cinfo, cinfo->comp_info[i].quant_tbl_no);
195 }
196 }
197
198 /* Output a scan header - we do one jvideo compress buffer as a scan */
199 void emit_sos(cinfo, length)
200 cInfo *cinfo;
201 int length;
202 {
203 int i;
204 static int compId[] = {IdY, IdCb, IdCr};
205 static int compTbl[] = {tabLUM, tabCRM, tabCRM};
206 emit_marker(cinfo, M_SOS);
207
208 emit_2bytes(cinfo, 2 * (sizeof(compId)/sizeof(int)) + 2 + 1 + 3);/* length */
209 emitByte(cinfo, (sizeof(compId)/sizeof(int))); /* numb components */
210 for (i = 0; i < (sizeof(compId)/sizeof(int)); i++) {
211 int tbl = compTbl[i];
212 emitByte(cinfo, compId[i]);
213 emitByte(cinfo, (tbl<< 4) /* DC bit */
214 + tbl); /* AC bit */
215 }
216 emitByte(cinfo, 0); /* Spectral selection start = 0 for seq DCT */
217 emitByte(cinfo, DCTSIZE2-1); /* Spectral selection end = 63 for seq DCT */
218 emitByte(cinfo, 0); /* Successive approximation = 0 for seq DCT */
219 }
220
221 void emit_jfif_app0(cinfo)
222 cInfo *cinfo;
223 {
224 emit_marker(cinfo, M_APP0);
225 emit_2bytes(cinfo, 16); /* length */
226 emitByte(cinfo, 'J');
227 emitByte(cinfo, 'F');
228 emitByte(cinfo, 'I');
229 emitByte(cinfo, 'F');
230 emitByte(cinfo, 0);
231 emit_2bytes(cinfo, 0x0101); /* version 1.01 */
232 emitByte(cinfo, 0); /* next 2 -> pixel aspect ratio */
233 emit_2bytes(cinfo, 1);
234 if (cinfo->image_width > 500)
235 emit_2bytes(cinfo, 2);
236 else
237 emit_2bytes(cinfo, 1);
238 emitByte(cinfo, 0); /* No 'Thumbnail' */
239 emitByte(cinfo, 0);
240 }
241
242 void dumpJfifFrame(wfd, compBuf, length, width, height, qFactor, jfifApp)
243 int wfd;
244 char *compBuf;
245 int width, height, qFactor, jfifApp;
246 {
247 int i;
248
249 cInfo ccc;
250 cInfo *cinfo = &ccc;
251
252 cinfo->wfd = wfd;
253 cinfo->userInfo = (void *) wfd;
254 cinfo->image_width = width;
255 cinfo->image_height = height;
256 cinfo->data_precision = 8;
257 cinfo->num_components = 3; /* Y Cb Cr */
258 cinfo->comp_info[0].component_id = IdY;
259 cinfo->comp_info[0].h_samp_factor = 2;
260 cinfo->comp_info[0].v_samp_factor = 1;
261 cinfo->comp_info[0].quant_tbl_no = tabLUM; /* (luminence table) */
262 cinfo->comp_info[1].component_id = IdCb;
263 cinfo->comp_info[1].h_samp_factor = 1;
264 cinfo->comp_info[1].v_samp_factor = 1;
265 cinfo->comp_info[1].quant_tbl_no = tabCRM;
266 cinfo->comp_info[2].component_id = IdCr;
267 cinfo->comp_info[2].h_samp_factor = 1;
268 cinfo->comp_info[2].v_samp_factor = 1;
269 cinfo->comp_info[2].quant_tbl_no = tabCRM;
270 cinfo->emit_byte = wrbyte;
271 emit_marker(cinfo, M_SOI);
272 if (jfifApp) emit_jfif_app0(cinfo);
273 emit_dqts(cinfo, qFactor);
274 emit_sof(cinfo, M_SOF0); /* SOF0 is baseline (8bit) DCT */
275 emit_dhts(cinfo);
276 emit_sos(cinfo, length);
277
278 /* Remove the trailing zeros inserted by the DMA process */
279 #ifdef notdef
280 while(compBuf[length] == 0) length--;
281 length++;
282 #endif
283 write(cinfo->wfd, compBuf, length);
284 emit_marker(cinfo, M_EOI);
285 }
286
287 void genJfif(compBuf, length, width, height, qFactor, wrByte, wrBlock, info)
288 char *compBuf;
289 int length, width, height, qFactor;
290 void (*wrByte)();
291 void (*wrBlock)();
292 void *info;
293 {
294 int i;
295
296 cInfo ccc;
297 cInfo *cinfo = &ccc;
298
299 cinfo->image_width = width;
300 cinfo->image_height = height;
301 cinfo->data_precision = 8;
302 cinfo->num_components = 3; /* Y Cb Cr */
303 cinfo->comp_info[0].component_id = IdY;
304 cinfo->comp_info[0].h_samp_factor = 2;
305 cinfo->comp_info[0].v_samp_factor = 1;
306 cinfo->comp_info[0].quant_tbl_no = tabLUM; /* (luminence table) */
307 cinfo->comp_info[1].component_id = IdCb;
308 cinfo->comp_info[1].h_samp_factor = 1;
309 cinfo->comp_info[1].v_samp_factor = 1;
310 cinfo->comp_info[1].quant_tbl_no = tabCRM;
311 cinfo->comp_info[2].component_id = IdCr;
312 cinfo->comp_info[2].h_samp_factor = 1;
313 cinfo->comp_info[2].v_samp_factor = 1;
314 cinfo->comp_info[2].quant_tbl_no = tabCRM;
315 cinfo->emit_byte = wrByte;
316 cinfo->userInfo = info;
317
318 emit_marker(cinfo, M_SOI);
319 emit_jfif_app0(cinfo);
320 emit_dqts(cinfo, qFactor);
321 emit_sof(cinfo, M_SOF0); /* SOF0 is baseline (8bit) DCT */
322 emit_dhts(cinfo);
323 emit_sos(cinfo, length);
324
325 /* Remove the trailing zeros inserted by the DMA process */
326 while(compBuf[length] == 0) length--;
327 length++;
328 (*wrBlock)(cinfo->wfd, compBuf, length);
329 emit_marker(cinfo, M_EOI);
330 }
331
332
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.