Path: blob/master/thirdparty/libjpeg-turbo/src/jcmarker.c
9904 views
/*1* jcmarker.c2*3* This file was part of the Independent JPEG Group's software:4* Copyright (C) 1991-1998, Thomas G. Lane.5* Modified 2003-2010 by Guido Vollbeding.6* Lossless JPEG Modifications:7* Copyright (C) 1999, Ken Murchison.8* libjpeg-turbo Modifications:9* Copyright (C) 2010, 2022, D. R. Commander.10* For conditions of distribution and use, see the accompanying README.ijg11* file.12*13* This file contains routines to write JPEG datastream markers.14*/1516#define JPEG_INTERNALS17#include "jinclude.h"18#include "jpeglib.h"19#include "jpegapicomp.h"202122typedef enum { /* JPEG marker codes */23M_SOF0 = 0xc0,24M_SOF1 = 0xc1,25M_SOF2 = 0xc2,26M_SOF3 = 0xc3,2728M_SOF5 = 0xc5,29M_SOF6 = 0xc6,30M_SOF7 = 0xc7,3132M_JPG = 0xc8,33M_SOF9 = 0xc9,34M_SOF10 = 0xca,35M_SOF11 = 0xcb,3637M_SOF13 = 0xcd,38M_SOF14 = 0xce,39M_SOF15 = 0xcf,4041M_DHT = 0xc4,4243M_DAC = 0xcc,4445M_RST0 = 0xd0,46M_RST1 = 0xd1,47M_RST2 = 0xd2,48M_RST3 = 0xd3,49M_RST4 = 0xd4,50M_RST5 = 0xd5,51M_RST6 = 0xd6,52M_RST7 = 0xd7,5354M_SOI = 0xd8,55M_EOI = 0xd9,56M_SOS = 0xda,57M_DQT = 0xdb,58M_DNL = 0xdc,59M_DRI = 0xdd,60M_DHP = 0xde,61M_EXP = 0xdf,6263M_APP0 = 0xe0,64M_APP1 = 0xe1,65M_APP2 = 0xe2,66M_APP3 = 0xe3,67M_APP4 = 0xe4,68M_APP5 = 0xe5,69M_APP6 = 0xe6,70M_APP7 = 0xe7,71M_APP8 = 0xe8,72M_APP9 = 0xe9,73M_APP10 = 0xea,74M_APP11 = 0xeb,75M_APP12 = 0xec,76M_APP13 = 0xed,77M_APP14 = 0xee,78M_APP15 = 0xef,7980M_JPG0 = 0xf0,81M_JPG13 = 0xfd,82M_COM = 0xfe,8384M_TEM = 0x01,8586M_ERROR = 0x10087} JPEG_MARKER;888990/* Private state */9192typedef struct {93struct jpeg_marker_writer pub; /* public fields */9495unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */96} my_marker_writer;9798typedef my_marker_writer *my_marker_ptr;99100101/*102* Basic output routines.103*104* Note that we do not support suspension while writing a marker.105* Therefore, an application using suspension must ensure that there is106* enough buffer space for the initial markers (typ. 600-700 bytes) before107* calling jpeg_start_compress, and enough space to write the trailing EOI108* (a few bytes) before calling jpeg_finish_compress. Multipass compression109* modes are not supported at all with suspension, so those two are the only110* points where markers will be written.111*/112113LOCAL(void)114emit_byte(j_compress_ptr cinfo, int val)115/* Emit a byte */116{117struct jpeg_destination_mgr *dest = cinfo->dest;118119*(dest->next_output_byte)++ = (JOCTET)val;120if (--dest->free_in_buffer == 0) {121if (!(*dest->empty_output_buffer) (cinfo))122ERREXIT(cinfo, JERR_CANT_SUSPEND);123}124}125126127LOCAL(void)128emit_marker(j_compress_ptr cinfo, JPEG_MARKER mark)129/* Emit a marker code */130{131emit_byte(cinfo, 0xFF);132emit_byte(cinfo, (int)mark);133}134135136LOCAL(void)137emit_2bytes(j_compress_ptr cinfo, int value)138/* Emit a 2-byte integer; these are always MSB first in JPEG files */139{140emit_byte(cinfo, (value >> 8) & 0xFF);141emit_byte(cinfo, value & 0xFF);142}143144145/*146* Routines to write specific marker types.147*/148149LOCAL(int)150emit_dqt(j_compress_ptr cinfo, int index)151/* Emit a DQT marker */152/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */153{154JQUANT_TBL *qtbl = cinfo->quant_tbl_ptrs[index];155int prec;156int i;157158if (qtbl == NULL)159ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);160161prec = 0;162for (i = 0; i < DCTSIZE2; i++) {163if (qtbl->quantval[i] > 255)164prec = 1;165}166167if (!qtbl->sent_table) {168emit_marker(cinfo, M_DQT);169170emit_2bytes(cinfo, prec ? DCTSIZE2 * 2 + 1 + 2 : DCTSIZE2 + 1 + 2);171172emit_byte(cinfo, index + (prec << 4));173174for (i = 0; i < DCTSIZE2; i++) {175/* The table entries must be emitted in zigzag order. */176unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];177if (prec)178emit_byte(cinfo, (int)(qval >> 8));179emit_byte(cinfo, (int)(qval & 0xFF));180}181182qtbl->sent_table = TRUE;183}184185return prec;186}187188189LOCAL(void)190emit_dht(j_compress_ptr cinfo, int index, boolean is_ac)191/* Emit a DHT marker */192{193JHUFF_TBL *htbl;194int length, i;195196if (is_ac) {197htbl = cinfo->ac_huff_tbl_ptrs[index];198index += 0x10; /* output index has AC bit set */199} else {200htbl = cinfo->dc_huff_tbl_ptrs[index];201}202203if (htbl == NULL)204ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index);205206if (!htbl->sent_table) {207emit_marker(cinfo, M_DHT);208209length = 0;210for (i = 1; i <= 16; i++)211length += htbl->bits[i];212213emit_2bytes(cinfo, length + 2 + 1 + 16);214emit_byte(cinfo, index);215216for (i = 1; i <= 16; i++)217emit_byte(cinfo, htbl->bits[i]);218219for (i = 0; i < length; i++)220emit_byte(cinfo, htbl->huffval[i]);221222htbl->sent_table = TRUE;223}224}225226227LOCAL(void)228emit_dac(j_compress_ptr cinfo)229/* Emit a DAC marker */230/* Since the useful info is so small, we want to emit all the tables in */231/* one DAC marker. Therefore this routine does its own scan of the table. */232{233#ifdef C_ARITH_CODING_SUPPORTED234char dc_in_use[NUM_ARITH_TBLS];235char ac_in_use[NUM_ARITH_TBLS];236int length, i;237jpeg_component_info *compptr;238239for (i = 0; i < NUM_ARITH_TBLS; i++)240dc_in_use[i] = ac_in_use[i] = 0;241242for (i = 0; i < cinfo->comps_in_scan; i++) {243compptr = cinfo->cur_comp_info[i];244/* DC needs no table for refinement scan */245if (cinfo->Ss == 0 && cinfo->Ah == 0)246dc_in_use[compptr->dc_tbl_no] = 1;247/* AC needs no table when not present */248if (cinfo->Se)249ac_in_use[compptr->ac_tbl_no] = 1;250}251252length = 0;253for (i = 0; i < NUM_ARITH_TBLS; i++)254length += dc_in_use[i] + ac_in_use[i];255256if (length) {257emit_marker(cinfo, M_DAC);258259emit_2bytes(cinfo, length * 2 + 2);260261for (i = 0; i < NUM_ARITH_TBLS; i++) {262if (dc_in_use[i]) {263emit_byte(cinfo, i);264emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i] << 4));265}266if (ac_in_use[i]) {267emit_byte(cinfo, i + 0x10);268emit_byte(cinfo, cinfo->arith_ac_K[i]);269}270}271}272#endif /* C_ARITH_CODING_SUPPORTED */273}274275276LOCAL(void)277emit_dri(j_compress_ptr cinfo)278/* Emit a DRI marker */279{280emit_marker(cinfo, M_DRI);281282emit_2bytes(cinfo, 4); /* fixed length */283284emit_2bytes(cinfo, (int)cinfo->restart_interval);285}286287288LOCAL(void)289emit_sof(j_compress_ptr cinfo, JPEG_MARKER code)290/* Emit a SOF marker */291{292int ci;293jpeg_component_info *compptr;294295emit_marker(cinfo, code);296297emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */298299/* Make sure image isn't bigger than SOF field can handle */300if ((long)cinfo->_jpeg_height > 65535L || (long)cinfo->_jpeg_width > 65535L)301ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int)65535);302303emit_byte(cinfo, cinfo->data_precision);304emit_2bytes(cinfo, (int)cinfo->_jpeg_height);305emit_2bytes(cinfo, (int)cinfo->_jpeg_width);306307emit_byte(cinfo, cinfo->num_components);308309for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;310ci++, compptr++) {311emit_byte(cinfo, compptr->component_id);312emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor);313emit_byte(cinfo, compptr->quant_tbl_no);314}315}316317318LOCAL(void)319emit_sos(j_compress_ptr cinfo)320/* Emit a SOS marker */321{322int i, td, ta;323jpeg_component_info *compptr;324325emit_marker(cinfo, M_SOS);326327emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */328329emit_byte(cinfo, cinfo->comps_in_scan);330331for (i = 0; i < cinfo->comps_in_scan; i++) {332compptr = cinfo->cur_comp_info[i];333emit_byte(cinfo, compptr->component_id);334335/* We emit 0 for unused field(s); this is recommended by the P&M text336* but does not seem to be specified in the standard.337*/338339/* DC needs no table for refinement scan */340td = cinfo->Ss == 0 && cinfo->Ah == 0 ? compptr->dc_tbl_no : 0;341/* AC needs no table when not present */342ta = cinfo->Se ? compptr->ac_tbl_no : 0;343344emit_byte(cinfo, (td << 4) + ta);345}346347emit_byte(cinfo, cinfo->Ss);348emit_byte(cinfo, cinfo->Se);349emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);350}351352353LOCAL(void)354emit_jfif_app0(j_compress_ptr cinfo)355/* Emit a JFIF-compliant APP0 marker */356{357/*358* Length of APP0 block (2 bytes)359* Block ID (4 bytes - ASCII "JFIF")360* Zero byte (1 byte to terminate the ID string)361* Version Major, Minor (2 bytes - major first)362* Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)363* Xdpu (2 bytes - dots per unit horizontal)364* Ydpu (2 bytes - dots per unit vertical)365* Thumbnail X size (1 byte)366* Thumbnail Y size (1 byte)367*/368369emit_marker(cinfo, M_APP0);370371emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */372373emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */374emit_byte(cinfo, 0x46);375emit_byte(cinfo, 0x49);376emit_byte(cinfo, 0x46);377emit_byte(cinfo, 0);378emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */379emit_byte(cinfo, cinfo->JFIF_minor_version);380emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */381emit_2bytes(cinfo, (int)cinfo->X_density);382emit_2bytes(cinfo, (int)cinfo->Y_density);383emit_byte(cinfo, 0); /* No thumbnail image */384emit_byte(cinfo, 0);385}386387388LOCAL(void)389emit_adobe_app14(j_compress_ptr cinfo)390/* Emit an Adobe APP14 marker */391{392/*393* Length of APP14 block (2 bytes)394* Block ID (5 bytes - ASCII "Adobe")395* Version Number (2 bytes - currently 100)396* Flags0 (2 bytes - currently 0)397* Flags1 (2 bytes - currently 0)398* Color transform (1 byte)399*400* Although Adobe TN 5116 mentions Version = 101, all the Adobe files401* now in circulation seem to use Version = 100, so that's what we write.402*403* We write the color transform byte as 1 if the JPEG color space is404* YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with405* whether the encoder performed a transformation, which is pretty useless.406*/407408emit_marker(cinfo, M_APP14);409410emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */411412emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */413emit_byte(cinfo, 0x64);414emit_byte(cinfo, 0x6F);415emit_byte(cinfo, 0x62);416emit_byte(cinfo, 0x65);417emit_2bytes(cinfo, 100); /* Version */418emit_2bytes(cinfo, 0); /* Flags0 */419emit_2bytes(cinfo, 0); /* Flags1 */420switch (cinfo->jpeg_color_space) {421case JCS_YCbCr:422emit_byte(cinfo, 1); /* Color transform = 1 */423break;424case JCS_YCCK:425emit_byte(cinfo, 2); /* Color transform = 2 */426break;427default:428emit_byte(cinfo, 0); /* Color transform = 0 */429break;430}431}432433434/*435* These routines allow writing an arbitrary marker with parameters.436* The only intended use is to emit COM or APPn markers after calling437* write_file_header and before calling write_frame_header.438* Other uses are not guaranteed to produce desirable results.439* Counting the parameter bytes properly is the caller's responsibility.440*/441442METHODDEF(void)443write_marker_header(j_compress_ptr cinfo, int marker, unsigned int datalen)444/* Emit an arbitrary marker header */445{446if (datalen > (unsigned int)65533) /* safety check */447ERREXIT(cinfo, JERR_BAD_LENGTH);448449emit_marker(cinfo, (JPEG_MARKER)marker);450451emit_2bytes(cinfo, (int)(datalen + 2)); /* total length */452}453454METHODDEF(void)455write_marker_byte(j_compress_ptr cinfo, int val)456/* Emit one byte of marker parameters following write_marker_header */457{458emit_byte(cinfo, val);459}460461462/*463* Write datastream header.464* This consists of an SOI and optional APPn markers.465* We recommend use of the JFIF marker, but not the Adobe marker,466* when using YCbCr or grayscale data. The JFIF marker should NOT467* be used for any other JPEG colorspace. The Adobe marker is helpful468* to distinguish RGB, CMYK, and YCCK colorspaces.469* Note that an application can write additional header markers after470* jpeg_start_compress returns.471*/472473METHODDEF(void)474write_file_header(j_compress_ptr cinfo)475{476my_marker_ptr marker = (my_marker_ptr)cinfo->marker;477478emit_marker(cinfo, M_SOI); /* first the SOI */479480/* SOI is defined to reset restart interval to 0 */481marker->last_restart_interval = 0;482483if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */484emit_jfif_app0(cinfo);485if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */486emit_adobe_app14(cinfo);487}488489490/*491* Write frame header.492* This consists of DQT and SOFn markers.493* Note that we do not emit the SOF until we have emitted the DQT(s).494* This avoids compatibility problems with incorrect implementations that495* try to error-check the quant table numbers as soon as they see the SOF.496*/497498METHODDEF(void)499write_frame_header(j_compress_ptr cinfo)500{501int ci, prec = 0;502boolean is_baseline;503jpeg_component_info *compptr;504505if (!cinfo->master->lossless) {506/* Emit DQT for each quantization table.507* Note that emit_dqt() suppresses any duplicate tables.508*/509for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;510ci++, compptr++) {511prec += emit_dqt(cinfo, compptr->quant_tbl_no);512}513/* now prec is nonzero iff there are any 16-bit quant tables. */514}515516/* Check for a non-baseline specification.517* Note we assume that Huffman table numbers won't be changed later.518*/519if (cinfo->arith_code || cinfo->progressive_mode ||520cinfo->master->lossless || cinfo->data_precision != 8) {521is_baseline = FALSE;522} else {523is_baseline = TRUE;524for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;525ci++, compptr++) {526if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)527is_baseline = FALSE;528}529if (prec && is_baseline) {530is_baseline = FALSE;531/* If it's baseline except for quantizer size, warn the user */532TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);533}534}535536/* Emit the proper SOF marker */537if (cinfo->arith_code) {538if (cinfo->progressive_mode)539emit_sof(cinfo, M_SOF10); /* SOF code for progressive arithmetic */540else541emit_sof(cinfo, M_SOF9); /* SOF code for sequential arithmetic */542} else {543if (cinfo->progressive_mode)544emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */545else if (cinfo->master->lossless)546emit_sof(cinfo, M_SOF3); /* SOF code for lossless Huffman */547else if (is_baseline)548emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */549else550emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */551}552}553554555/*556* Write scan header.557* This consists of DHT or DAC markers, optional DRI, and SOS.558* Compressed data will be written following the SOS.559*/560561METHODDEF(void)562write_scan_header(j_compress_ptr cinfo)563{564my_marker_ptr marker = (my_marker_ptr)cinfo->marker;565int i;566jpeg_component_info *compptr;567568if (cinfo->arith_code) {569/* Emit arith conditioning info. We may have some duplication570* if the file has multiple scans, but it's so small it's hardly571* worth worrying about.572*/573emit_dac(cinfo);574} else {575/* Emit Huffman tables.576* Note that emit_dht() suppresses any duplicate tables.577*/578for (i = 0; i < cinfo->comps_in_scan; i++) {579compptr = cinfo->cur_comp_info[i];580/* DC needs no table for refinement scan */581if ((cinfo->Ss == 0 && cinfo->Ah == 0) || cinfo->master->lossless)582emit_dht(cinfo, compptr->dc_tbl_no, FALSE);583/* AC needs no table when not present, and lossless mode uses only DC584tables. */585if (cinfo->Se && !cinfo->master->lossless)586emit_dht(cinfo, compptr->ac_tbl_no, TRUE);587}588}589590/* Emit DRI if required --- note that DRI value could change for each scan.591* We avoid wasting space with unnecessary DRIs, however.592*/593if (cinfo->restart_interval != marker->last_restart_interval) {594emit_dri(cinfo);595marker->last_restart_interval = cinfo->restart_interval;596}597598emit_sos(cinfo);599}600601602/*603* Write datastream trailer.604*/605606METHODDEF(void)607write_file_trailer(j_compress_ptr cinfo)608{609emit_marker(cinfo, M_EOI);610}611612613/*614* Write an abbreviated table-specification datastream.615* This consists of SOI, DQT and DHT tables, and EOI.616* Any table that is defined and not marked sent_table = TRUE will be617* emitted. Note that all tables will be marked sent_table = TRUE at exit.618*/619620METHODDEF(void)621write_tables_only(j_compress_ptr cinfo)622{623int i;624625emit_marker(cinfo, M_SOI);626627for (i = 0; i < NUM_QUANT_TBLS; i++) {628if (cinfo->quant_tbl_ptrs[i] != NULL)629(void)emit_dqt(cinfo, i);630}631632if (!cinfo->arith_code) {633for (i = 0; i < NUM_HUFF_TBLS; i++) {634if (cinfo->dc_huff_tbl_ptrs[i] != NULL)635emit_dht(cinfo, i, FALSE);636if (cinfo->ac_huff_tbl_ptrs[i] != NULL)637emit_dht(cinfo, i, TRUE);638}639}640641emit_marker(cinfo, M_EOI);642}643644645/*646* Initialize the marker writer module.647*/648649GLOBAL(void)650jinit_marker_writer(j_compress_ptr cinfo)651{652my_marker_ptr marker;653654/* Create the subobject */655marker = (my_marker_ptr)656(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,657sizeof(my_marker_writer));658cinfo->marker = (struct jpeg_marker_writer *)marker;659/* Initialize method pointers */660marker->pub.write_file_header = write_file_header;661marker->pub.write_frame_header = write_frame_header;662marker->pub.write_scan_header = write_scan_header;663marker->pub.write_file_trailer = write_file_trailer;664marker->pub.write_tables_only = write_tables_only;665marker->pub.write_marker_header = write_marker_header;666marker->pub.write_marker_byte = write_marker_byte;667/* Initialize private state */668marker->last_restart_interval = 0;669}670671672