istereo
diff libs/libjpeg/jcmarker.c @ 26:862a3329a8f0
wohooo, added a shitload of code from zlib/libpng/libjpeg. When the good lord was raining shared libraries the iphone held a fucking umbrella...
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Thu, 08 Sep 2011 06:28:38 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/libjpeg/jcmarker.c Thu Sep 08 06:28:38 2011 +0300 1.3 @@ -0,0 +1,664 @@ 1.4 +/* 1.5 + * jcmarker.c 1.6 + * 1.7 + * Copyright (C) 1991-1998, Thomas G. Lane. 1.8 + * This file is part of the Independent JPEG Group's software. 1.9 + * For conditions of distribution and use, see the accompanying README file. 1.10 + * 1.11 + * This file contains routines to write JPEG datastream markers. 1.12 + */ 1.13 + 1.14 +#define JPEG_INTERNALS 1.15 +#include "jinclude.h" 1.16 +#include "jpeglib.h" 1.17 + 1.18 + 1.19 +typedef enum { /* JPEG marker codes */ 1.20 + M_SOF0 = 0xc0, 1.21 + M_SOF1 = 0xc1, 1.22 + M_SOF2 = 0xc2, 1.23 + M_SOF3 = 0xc3, 1.24 + 1.25 + M_SOF5 = 0xc5, 1.26 + M_SOF6 = 0xc6, 1.27 + M_SOF7 = 0xc7, 1.28 + 1.29 + M_JPG = 0xc8, 1.30 + M_SOF9 = 0xc9, 1.31 + M_SOF10 = 0xca, 1.32 + M_SOF11 = 0xcb, 1.33 + 1.34 + M_SOF13 = 0xcd, 1.35 + M_SOF14 = 0xce, 1.36 + M_SOF15 = 0xcf, 1.37 + 1.38 + M_DHT = 0xc4, 1.39 + 1.40 + M_DAC = 0xcc, 1.41 + 1.42 + M_RST0 = 0xd0, 1.43 + M_RST1 = 0xd1, 1.44 + M_RST2 = 0xd2, 1.45 + M_RST3 = 0xd3, 1.46 + M_RST4 = 0xd4, 1.47 + M_RST5 = 0xd5, 1.48 + M_RST6 = 0xd6, 1.49 + M_RST7 = 0xd7, 1.50 + 1.51 + M_SOI = 0xd8, 1.52 + M_EOI = 0xd9, 1.53 + M_SOS = 0xda, 1.54 + M_DQT = 0xdb, 1.55 + M_DNL = 0xdc, 1.56 + M_DRI = 0xdd, 1.57 + M_DHP = 0xde, 1.58 + M_EXP = 0xdf, 1.59 + 1.60 + M_APP0 = 0xe0, 1.61 + M_APP1 = 0xe1, 1.62 + M_APP2 = 0xe2, 1.63 + M_APP3 = 0xe3, 1.64 + M_APP4 = 0xe4, 1.65 + M_APP5 = 0xe5, 1.66 + M_APP6 = 0xe6, 1.67 + M_APP7 = 0xe7, 1.68 + M_APP8 = 0xe8, 1.69 + M_APP9 = 0xe9, 1.70 + M_APP10 = 0xea, 1.71 + M_APP11 = 0xeb, 1.72 + M_APP12 = 0xec, 1.73 + M_APP13 = 0xed, 1.74 + M_APP14 = 0xee, 1.75 + M_APP15 = 0xef, 1.76 + 1.77 + M_JPG0 = 0xf0, 1.78 + M_JPG13 = 0xfd, 1.79 + M_COM = 0xfe, 1.80 + 1.81 + M_TEM = 0x01, 1.82 + 1.83 + M_ERROR = 0x100 1.84 +} JPEG_MARKER; 1.85 + 1.86 + 1.87 +/* Private state */ 1.88 + 1.89 +typedef struct { 1.90 + struct jpeg_marker_writer pub; /* public fields */ 1.91 + 1.92 + unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */ 1.93 +} my_marker_writer; 1.94 + 1.95 +typedef my_marker_writer * my_marker_ptr; 1.96 + 1.97 + 1.98 +/* 1.99 + * Basic output routines. 1.100 + * 1.101 + * Note that we do not support suspension while writing a marker. 1.102 + * Therefore, an application using suspension must ensure that there is 1.103 + * enough buffer space for the initial markers (typ. 600-700 bytes) before 1.104 + * calling jpeg_start_compress, and enough space to write the trailing EOI 1.105 + * (a few bytes) before calling jpeg_finish_compress. Multipass compression 1.106 + * modes are not supported at all with suspension, so those two are the only 1.107 + * points where markers will be written. 1.108 + */ 1.109 + 1.110 +LOCAL(void) 1.111 +emit_byte (j_compress_ptr cinfo, int val) 1.112 +/* Emit a byte */ 1.113 +{ 1.114 + struct jpeg_destination_mgr * dest = cinfo->dest; 1.115 + 1.116 + *(dest->next_output_byte)++ = (JOCTET) val; 1.117 + if (--dest->free_in_buffer == 0) { 1.118 + if (! (*dest->empty_output_buffer) (cinfo)) 1.119 + ERREXIT(cinfo, JERR_CANT_SUSPEND); 1.120 + } 1.121 +} 1.122 + 1.123 + 1.124 +LOCAL(void) 1.125 +emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark) 1.126 +/* Emit a marker code */ 1.127 +{ 1.128 + emit_byte(cinfo, 0xFF); 1.129 + emit_byte(cinfo, (int) mark); 1.130 +} 1.131 + 1.132 + 1.133 +LOCAL(void) 1.134 +emit_2bytes (j_compress_ptr cinfo, int value) 1.135 +/* Emit a 2-byte integer; these are always MSB first in JPEG files */ 1.136 +{ 1.137 + emit_byte(cinfo, (value >> 8) & 0xFF); 1.138 + emit_byte(cinfo, value & 0xFF); 1.139 +} 1.140 + 1.141 + 1.142 +/* 1.143 + * Routines to write specific marker types. 1.144 + */ 1.145 + 1.146 +LOCAL(int) 1.147 +emit_dqt (j_compress_ptr cinfo, int index) 1.148 +/* Emit a DQT marker */ 1.149 +/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */ 1.150 +{ 1.151 + JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index]; 1.152 + int prec; 1.153 + int i; 1.154 + 1.155 + if (qtbl == NULL) 1.156 + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index); 1.157 + 1.158 + prec = 0; 1.159 + for (i = 0; i < DCTSIZE2; i++) { 1.160 + if (qtbl->quantval[i] > 255) 1.161 + prec = 1; 1.162 + } 1.163 + 1.164 + if (! qtbl->sent_table) { 1.165 + emit_marker(cinfo, M_DQT); 1.166 + 1.167 + emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2); 1.168 + 1.169 + emit_byte(cinfo, index + (prec<<4)); 1.170 + 1.171 + for (i = 0; i < DCTSIZE2; i++) { 1.172 + /* The table entries must be emitted in zigzag order. */ 1.173 + unsigned int qval = qtbl->quantval[jpeg_natural_order[i]]; 1.174 + if (prec) 1.175 + emit_byte(cinfo, (int) (qval >> 8)); 1.176 + emit_byte(cinfo, (int) (qval & 0xFF)); 1.177 + } 1.178 + 1.179 + qtbl->sent_table = TRUE; 1.180 + } 1.181 + 1.182 + return prec; 1.183 +} 1.184 + 1.185 + 1.186 +LOCAL(void) 1.187 +emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) 1.188 +/* Emit a DHT marker */ 1.189 +{ 1.190 + JHUFF_TBL * htbl; 1.191 + int length, i; 1.192 + 1.193 + if (is_ac) { 1.194 + htbl = cinfo->ac_huff_tbl_ptrs[index]; 1.195 + index += 0x10; /* output index has AC bit set */ 1.196 + } else { 1.197 + htbl = cinfo->dc_huff_tbl_ptrs[index]; 1.198 + } 1.199 + 1.200 + if (htbl == NULL) 1.201 + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index); 1.202 + 1.203 + if (! htbl->sent_table) { 1.204 + emit_marker(cinfo, M_DHT); 1.205 + 1.206 + length = 0; 1.207 + for (i = 1; i <= 16; i++) 1.208 + length += htbl->bits[i]; 1.209 + 1.210 + emit_2bytes(cinfo, length + 2 + 1 + 16); 1.211 + emit_byte(cinfo, index); 1.212 + 1.213 + for (i = 1; i <= 16; i++) 1.214 + emit_byte(cinfo, htbl->bits[i]); 1.215 + 1.216 + for (i = 0; i < length; i++) 1.217 + emit_byte(cinfo, htbl->huffval[i]); 1.218 + 1.219 + htbl->sent_table = TRUE; 1.220 + } 1.221 +} 1.222 + 1.223 + 1.224 +LOCAL(void) 1.225 +emit_dac (j_compress_ptr cinfo) 1.226 +/* Emit a DAC marker */ 1.227 +/* Since the useful info is so small, we want to emit all the tables in */ 1.228 +/* one DAC marker. Therefore this routine does its own scan of the table. */ 1.229 +{ 1.230 +#ifdef C_ARITH_CODING_SUPPORTED 1.231 + char dc_in_use[NUM_ARITH_TBLS]; 1.232 + char ac_in_use[NUM_ARITH_TBLS]; 1.233 + int length, i; 1.234 + jpeg_component_info *compptr; 1.235 + 1.236 + for (i = 0; i < NUM_ARITH_TBLS; i++) 1.237 + dc_in_use[i] = ac_in_use[i] = 0; 1.238 + 1.239 + for (i = 0; i < cinfo->comps_in_scan; i++) { 1.240 + compptr = cinfo->cur_comp_info[i]; 1.241 + dc_in_use[compptr->dc_tbl_no] = 1; 1.242 + ac_in_use[compptr->ac_tbl_no] = 1; 1.243 + } 1.244 + 1.245 + length = 0; 1.246 + for (i = 0; i < NUM_ARITH_TBLS; i++) 1.247 + length += dc_in_use[i] + ac_in_use[i]; 1.248 + 1.249 + emit_marker(cinfo, M_DAC); 1.250 + 1.251 + emit_2bytes(cinfo, length*2 + 2); 1.252 + 1.253 + for (i = 0; i < NUM_ARITH_TBLS; i++) { 1.254 + if (dc_in_use[i]) { 1.255 + emit_byte(cinfo, i); 1.256 + emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4)); 1.257 + } 1.258 + if (ac_in_use[i]) { 1.259 + emit_byte(cinfo, i + 0x10); 1.260 + emit_byte(cinfo, cinfo->arith_ac_K[i]); 1.261 + } 1.262 + } 1.263 +#endif /* C_ARITH_CODING_SUPPORTED */ 1.264 +} 1.265 + 1.266 + 1.267 +LOCAL(void) 1.268 +emit_dri (j_compress_ptr cinfo) 1.269 +/* Emit a DRI marker */ 1.270 +{ 1.271 + emit_marker(cinfo, M_DRI); 1.272 + 1.273 + emit_2bytes(cinfo, 4); /* fixed length */ 1.274 + 1.275 + emit_2bytes(cinfo, (int) cinfo->restart_interval); 1.276 +} 1.277 + 1.278 + 1.279 +LOCAL(void) 1.280 +emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) 1.281 +/* Emit a SOF marker */ 1.282 +{ 1.283 + int ci; 1.284 + jpeg_component_info *compptr; 1.285 + 1.286 + emit_marker(cinfo, code); 1.287 + 1.288 + emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */ 1.289 + 1.290 + /* Make sure image isn't bigger than SOF field can handle */ 1.291 + if ((long) cinfo->image_height > 65535L || 1.292 + (long) cinfo->image_width > 65535L) 1.293 + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535); 1.294 + 1.295 + emit_byte(cinfo, cinfo->data_precision); 1.296 + emit_2bytes(cinfo, (int) cinfo->image_height); 1.297 + emit_2bytes(cinfo, (int) cinfo->image_width); 1.298 + 1.299 + emit_byte(cinfo, cinfo->num_components); 1.300 + 1.301 + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 1.302 + ci++, compptr++) { 1.303 + emit_byte(cinfo, compptr->component_id); 1.304 + emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor); 1.305 + emit_byte(cinfo, compptr->quant_tbl_no); 1.306 + } 1.307 +} 1.308 + 1.309 + 1.310 +LOCAL(void) 1.311 +emit_sos (j_compress_ptr cinfo) 1.312 +/* Emit a SOS marker */ 1.313 +{ 1.314 + int i, td, ta; 1.315 + jpeg_component_info *compptr; 1.316 + 1.317 + emit_marker(cinfo, M_SOS); 1.318 + 1.319 + emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */ 1.320 + 1.321 + emit_byte(cinfo, cinfo->comps_in_scan); 1.322 + 1.323 + for (i = 0; i < cinfo->comps_in_scan; i++) { 1.324 + compptr = cinfo->cur_comp_info[i]; 1.325 + emit_byte(cinfo, compptr->component_id); 1.326 + td = compptr->dc_tbl_no; 1.327 + ta = compptr->ac_tbl_no; 1.328 + if (cinfo->progressive_mode) { 1.329 + /* Progressive mode: only DC or only AC tables are used in one scan; 1.330 + * furthermore, Huffman coding of DC refinement uses no table at all. 1.331 + * We emit 0 for unused field(s); this is recommended by the P&M text 1.332 + * but does not seem to be specified in the standard. 1.333 + */ 1.334 + if (cinfo->Ss == 0) { 1.335 + ta = 0; /* DC scan */ 1.336 + if (cinfo->Ah != 0 && !cinfo->arith_code) 1.337 + td = 0; /* no DC table either */ 1.338 + } else { 1.339 + td = 0; /* AC scan */ 1.340 + } 1.341 + } 1.342 + emit_byte(cinfo, (td << 4) + ta); 1.343 + } 1.344 + 1.345 + emit_byte(cinfo, cinfo->Ss); 1.346 + emit_byte(cinfo, cinfo->Se); 1.347 + emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al); 1.348 +} 1.349 + 1.350 + 1.351 +LOCAL(void) 1.352 +emit_jfif_app0 (j_compress_ptr cinfo) 1.353 +/* Emit a JFIF-compliant APP0 marker */ 1.354 +{ 1.355 + /* 1.356 + * Length of APP0 block (2 bytes) 1.357 + * Block ID (4 bytes - ASCII "JFIF") 1.358 + * Zero byte (1 byte to terminate the ID string) 1.359 + * Version Major, Minor (2 bytes - major first) 1.360 + * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm) 1.361 + * Xdpu (2 bytes - dots per unit horizontal) 1.362 + * Ydpu (2 bytes - dots per unit vertical) 1.363 + * Thumbnail X size (1 byte) 1.364 + * Thumbnail Y size (1 byte) 1.365 + */ 1.366 + 1.367 + emit_marker(cinfo, M_APP0); 1.368 + 1.369 + emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */ 1.370 + 1.371 + emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */ 1.372 + emit_byte(cinfo, 0x46); 1.373 + emit_byte(cinfo, 0x49); 1.374 + emit_byte(cinfo, 0x46); 1.375 + emit_byte(cinfo, 0); 1.376 + emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */ 1.377 + emit_byte(cinfo, cinfo->JFIF_minor_version); 1.378 + emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */ 1.379 + emit_2bytes(cinfo, (int) cinfo->X_density); 1.380 + emit_2bytes(cinfo, (int) cinfo->Y_density); 1.381 + emit_byte(cinfo, 0); /* No thumbnail image */ 1.382 + emit_byte(cinfo, 0); 1.383 +} 1.384 + 1.385 + 1.386 +LOCAL(void) 1.387 +emit_adobe_app14 (j_compress_ptr cinfo) 1.388 +/* Emit an Adobe APP14 marker */ 1.389 +{ 1.390 + /* 1.391 + * Length of APP14 block (2 bytes) 1.392 + * Block ID (5 bytes - ASCII "Adobe") 1.393 + * Version Number (2 bytes - currently 100) 1.394 + * Flags0 (2 bytes - currently 0) 1.395 + * Flags1 (2 bytes - currently 0) 1.396 + * Color transform (1 byte) 1.397 + * 1.398 + * Although Adobe TN 5116 mentions Version = 101, all the Adobe files 1.399 + * now in circulation seem to use Version = 100, so that's what we write. 1.400 + * 1.401 + * We write the color transform byte as 1 if the JPEG color space is 1.402 + * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with 1.403 + * whether the encoder performed a transformation, which is pretty useless. 1.404 + */ 1.405 + 1.406 + emit_marker(cinfo, M_APP14); 1.407 + 1.408 + emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */ 1.409 + 1.410 + emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */ 1.411 + emit_byte(cinfo, 0x64); 1.412 + emit_byte(cinfo, 0x6F); 1.413 + emit_byte(cinfo, 0x62); 1.414 + emit_byte(cinfo, 0x65); 1.415 + emit_2bytes(cinfo, 100); /* Version */ 1.416 + emit_2bytes(cinfo, 0); /* Flags0 */ 1.417 + emit_2bytes(cinfo, 0); /* Flags1 */ 1.418 + switch (cinfo->jpeg_color_space) { 1.419 + case JCS_YCbCr: 1.420 + emit_byte(cinfo, 1); /* Color transform = 1 */ 1.421 + break; 1.422 + case JCS_YCCK: 1.423 + emit_byte(cinfo, 2); /* Color transform = 2 */ 1.424 + break; 1.425 + default: 1.426 + emit_byte(cinfo, 0); /* Color transform = 0 */ 1.427 + break; 1.428 + } 1.429 +} 1.430 + 1.431 + 1.432 +/* 1.433 + * These routines allow writing an arbitrary marker with parameters. 1.434 + * The only intended use is to emit COM or APPn markers after calling 1.435 + * write_file_header and before calling write_frame_header. 1.436 + * Other uses are not guaranteed to produce desirable results. 1.437 + * Counting the parameter bytes properly is the caller's responsibility. 1.438 + */ 1.439 + 1.440 +METHODDEF(void) 1.441 +write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen) 1.442 +/* Emit an arbitrary marker header */ 1.443 +{ 1.444 + if (datalen > (unsigned int) 65533) /* safety check */ 1.445 + ERREXIT(cinfo, JERR_BAD_LENGTH); 1.446 + 1.447 + emit_marker(cinfo, (JPEG_MARKER) marker); 1.448 + 1.449 + emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */ 1.450 +} 1.451 + 1.452 +METHODDEF(void) 1.453 +write_marker_byte (j_compress_ptr cinfo, int val) 1.454 +/* Emit one byte of marker parameters following write_marker_header */ 1.455 +{ 1.456 + emit_byte(cinfo, val); 1.457 +} 1.458 + 1.459 + 1.460 +/* 1.461 + * Write datastream header. 1.462 + * This consists of an SOI and optional APPn markers. 1.463 + * We recommend use of the JFIF marker, but not the Adobe marker, 1.464 + * when using YCbCr or grayscale data. The JFIF marker should NOT 1.465 + * be used for any other JPEG colorspace. The Adobe marker is helpful 1.466 + * to distinguish RGB, CMYK, and YCCK colorspaces. 1.467 + * Note that an application can write additional header markers after 1.468 + * jpeg_start_compress returns. 1.469 + */ 1.470 + 1.471 +METHODDEF(void) 1.472 +write_file_header (j_compress_ptr cinfo) 1.473 +{ 1.474 + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; 1.475 + 1.476 + emit_marker(cinfo, M_SOI); /* first the SOI */ 1.477 + 1.478 + /* SOI is defined to reset restart interval to 0 */ 1.479 + marker->last_restart_interval = 0; 1.480 + 1.481 + if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */ 1.482 + emit_jfif_app0(cinfo); 1.483 + if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */ 1.484 + emit_adobe_app14(cinfo); 1.485 +} 1.486 + 1.487 + 1.488 +/* 1.489 + * Write frame header. 1.490 + * This consists of DQT and SOFn markers. 1.491 + * Note that we do not emit the SOF until we have emitted the DQT(s). 1.492 + * This avoids compatibility problems with incorrect implementations that 1.493 + * try to error-check the quant table numbers as soon as they see the SOF. 1.494 + */ 1.495 + 1.496 +METHODDEF(void) 1.497 +write_frame_header (j_compress_ptr cinfo) 1.498 +{ 1.499 + int ci, prec; 1.500 + boolean is_baseline; 1.501 + jpeg_component_info *compptr; 1.502 + 1.503 + /* Emit DQT for each quantization table. 1.504 + * Note that emit_dqt() suppresses any duplicate tables. 1.505 + */ 1.506 + prec = 0; 1.507 + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 1.508 + ci++, compptr++) { 1.509 + prec += emit_dqt(cinfo, compptr->quant_tbl_no); 1.510 + } 1.511 + /* now prec is nonzero iff there are any 16-bit quant tables. */ 1.512 + 1.513 + /* Check for a non-baseline specification. 1.514 + * Note we assume that Huffman table numbers won't be changed later. 1.515 + */ 1.516 + if (cinfo->arith_code || cinfo->progressive_mode || 1.517 + cinfo->data_precision != 8) { 1.518 + is_baseline = FALSE; 1.519 + } else { 1.520 + is_baseline = TRUE; 1.521 + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 1.522 + ci++, compptr++) { 1.523 + if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1) 1.524 + is_baseline = FALSE; 1.525 + } 1.526 + if (prec && is_baseline) { 1.527 + is_baseline = FALSE; 1.528 + /* If it's baseline except for quantizer size, warn the user */ 1.529 + TRACEMS(cinfo, 0, JTRC_16BIT_TABLES); 1.530 + } 1.531 + } 1.532 + 1.533 + /* Emit the proper SOF marker */ 1.534 + if (cinfo->arith_code) { 1.535 + emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */ 1.536 + } else { 1.537 + if (cinfo->progressive_mode) 1.538 + emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ 1.539 + else if (is_baseline) 1.540 + emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */ 1.541 + else 1.542 + emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */ 1.543 + } 1.544 +} 1.545 + 1.546 + 1.547 +/* 1.548 + * Write scan header. 1.549 + * This consists of DHT or DAC markers, optional DRI, and SOS. 1.550 + * Compressed data will be written following the SOS. 1.551 + */ 1.552 + 1.553 +METHODDEF(void) 1.554 +write_scan_header (j_compress_ptr cinfo) 1.555 +{ 1.556 + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; 1.557 + int i; 1.558 + jpeg_component_info *compptr; 1.559 + 1.560 + if (cinfo->arith_code) { 1.561 + /* Emit arith conditioning info. We may have some duplication 1.562 + * if the file has multiple scans, but it's so small it's hardly 1.563 + * worth worrying about. 1.564 + */ 1.565 + emit_dac(cinfo); 1.566 + } else { 1.567 + /* Emit Huffman tables. 1.568 + * Note that emit_dht() suppresses any duplicate tables. 1.569 + */ 1.570 + for (i = 0; i < cinfo->comps_in_scan; i++) { 1.571 + compptr = cinfo->cur_comp_info[i]; 1.572 + if (cinfo->progressive_mode) { 1.573 + /* Progressive mode: only DC or only AC tables are used in one scan */ 1.574 + if (cinfo->Ss == 0) { 1.575 + if (cinfo->Ah == 0) /* DC needs no table for refinement scan */ 1.576 + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); 1.577 + } else { 1.578 + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); 1.579 + } 1.580 + } else { 1.581 + /* Sequential mode: need both DC and AC tables */ 1.582 + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); 1.583 + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); 1.584 + } 1.585 + } 1.586 + } 1.587 + 1.588 + /* Emit DRI if required --- note that DRI value could change for each scan. 1.589 + * We avoid wasting space with unnecessary DRIs, however. 1.590 + */ 1.591 + if (cinfo->restart_interval != marker->last_restart_interval) { 1.592 + emit_dri(cinfo); 1.593 + marker->last_restart_interval = cinfo->restart_interval; 1.594 + } 1.595 + 1.596 + emit_sos(cinfo); 1.597 +} 1.598 + 1.599 + 1.600 +/* 1.601 + * Write datastream trailer. 1.602 + */ 1.603 + 1.604 +METHODDEF(void) 1.605 +write_file_trailer (j_compress_ptr cinfo) 1.606 +{ 1.607 + emit_marker(cinfo, M_EOI); 1.608 +} 1.609 + 1.610 + 1.611 +/* 1.612 + * Write an abbreviated table-specification datastream. 1.613 + * This consists of SOI, DQT and DHT tables, and EOI. 1.614 + * Any table that is defined and not marked sent_table = TRUE will be 1.615 + * emitted. Note that all tables will be marked sent_table = TRUE at exit. 1.616 + */ 1.617 + 1.618 +METHODDEF(void) 1.619 +write_tables_only (j_compress_ptr cinfo) 1.620 +{ 1.621 + int i; 1.622 + 1.623 + emit_marker(cinfo, M_SOI); 1.624 + 1.625 + for (i = 0; i < NUM_QUANT_TBLS; i++) { 1.626 + if (cinfo->quant_tbl_ptrs[i] != NULL) 1.627 + (void) emit_dqt(cinfo, i); 1.628 + } 1.629 + 1.630 + if (! cinfo->arith_code) { 1.631 + for (i = 0; i < NUM_HUFF_TBLS; i++) { 1.632 + if (cinfo->dc_huff_tbl_ptrs[i] != NULL) 1.633 + emit_dht(cinfo, i, FALSE); 1.634 + if (cinfo->ac_huff_tbl_ptrs[i] != NULL) 1.635 + emit_dht(cinfo, i, TRUE); 1.636 + } 1.637 + } 1.638 + 1.639 + emit_marker(cinfo, M_EOI); 1.640 +} 1.641 + 1.642 + 1.643 +/* 1.644 + * Initialize the marker writer module. 1.645 + */ 1.646 + 1.647 +GLOBAL(void) 1.648 +jinit_marker_writer (j_compress_ptr cinfo) 1.649 +{ 1.650 + my_marker_ptr marker; 1.651 + 1.652 + /* Create the subobject */ 1.653 + marker = (my_marker_ptr) 1.654 + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 1.655 + SIZEOF(my_marker_writer)); 1.656 + cinfo->marker = (struct jpeg_marker_writer *) marker; 1.657 + /* Initialize method pointers */ 1.658 + marker->pub.write_file_header = write_file_header; 1.659 + marker->pub.write_frame_header = write_frame_header; 1.660 + marker->pub.write_scan_header = write_scan_header; 1.661 + marker->pub.write_file_trailer = write_file_trailer; 1.662 + marker->pub.write_tables_only = write_tables_only; 1.663 + marker->pub.write_marker_header = write_marker_header; 1.664 + marker->pub.write_marker_byte = write_marker_byte; 1.665 + /* Initialize private state */ 1.666 + marker->last_restart_interval = 0; 1.667 +}