Path: blob/master/thirdparty/libjpeg-turbo/src/jcapistd.c
9904 views
/*1* jcapistd.c2*3* This file was part of the Independent JPEG Group's software:4* Copyright (C) 1994-1996, Thomas G. Lane.5* libjpeg-turbo Modifications:6* Copyright (C) 2022, 2024, D. R. Commander.7* For conditions of distribution and use, see the accompanying README.ijg8* file.9*10* This file contains application interface code for the compression half11* of the JPEG library. These are the "standard" API routines that are12* used in the normal full-compression case. They are not used by a13* transcoding-only application. Note that if an application links in14* jpeg_start_compress, it will end up linking in the entire compressor.15* We thus must separate this file from jcapimin.c to avoid linking the16* whole compression library into a transcoder.17*/1819#define JPEG_INTERNALS20#include "jinclude.h"21#include "jpeglib.h"22#include "jsamplecomp.h"232425#if BITS_IN_JSAMPLE == 82627/*28* Compression initialization.29* Before calling this, all parameters and a data destination must be set up.30*31* We require a write_all_tables parameter as a failsafe check when writing32* multiple datastreams from the same compression object. Since prior runs33* will have left all the tables marked sent_table=TRUE, a subsequent run34* would emit an abbreviated stream (no tables) by default. This may be what35* is wanted, but for safety's sake it should not be the default behavior:36* programmers should have to make a deliberate choice to emit abbreviated37* images. Therefore the documentation and examples should encourage people38* to pass write_all_tables=TRUE; then it will take active thought to do the39* wrong thing.40*/4142GLOBAL(void)43jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables)44{45if (cinfo->global_state != CSTATE_START)46ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);4748if (write_all_tables)49jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */5051/* (Re)initialize error mgr and destination modules */52(*cinfo->err->reset_error_mgr) ((j_common_ptr)cinfo);53(*cinfo->dest->init_destination) (cinfo);54/* Perform master selection of active modules */55jinit_compress_master(cinfo);56/* Set up for the first pass */57(*cinfo->master->prepare_for_pass) (cinfo);58/* Ready for application to drive first pass through _jpeg_write_scanlines59* or _jpeg_write_raw_data.60*/61cinfo->next_scanline = 0;62cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);63}6465#endif666768/*69* Write some scanlines of data to the JPEG compressor.70*71* The return value will be the number of lines actually written.72* This should be less than the supplied num_lines only in case that73* the data destination module has requested suspension of the compressor,74* or if more than image_height scanlines are passed in.75*76* Note: we warn about excess calls to _jpeg_write_scanlines() since77* this likely signals an application programmer error. However,78* excess scanlines passed in the last valid call are *silently* ignored,79* so that the application need not adjust num_lines for end-of-image80* when using a multiple-scanline buffer.81*/8283GLOBAL(JDIMENSION)84_jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines,85JDIMENSION num_lines)86{87#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)88JDIMENSION row_ctr, rows_left;8990#ifdef C_LOSSLESS_SUPPORTED91if (cinfo->master->lossless) {92#if BITS_IN_JSAMPLE == 893if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)94#else95if (cinfo->data_precision > BITS_IN_JSAMPLE ||96cinfo->data_precision < BITS_IN_JSAMPLE - 3)97#endif98ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);99} else100#endif101{102if (cinfo->data_precision != BITS_IN_JSAMPLE)103ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);104}105106if (cinfo->global_state != CSTATE_SCANNING)107ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);108if (cinfo->next_scanline >= cinfo->image_height)109WARNMS(cinfo, JWRN_TOO_MUCH_DATA);110111/* Call progress monitor hook if present */112if (cinfo->progress != NULL) {113cinfo->progress->pass_counter = (long)cinfo->next_scanline;114cinfo->progress->pass_limit = (long)cinfo->image_height;115(*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo);116}117118/* Give master control module another chance if this is first call to119* _jpeg_write_scanlines. This lets output of the frame/scan headers be120* delayed so that application can write COM, etc, markers between121* jpeg_start_compress and _jpeg_write_scanlines.122*/123if (cinfo->master->call_pass_startup)124(*cinfo->master->pass_startup) (cinfo);125126/* Ignore any extra scanlines at bottom of image. */127rows_left = cinfo->image_height - cinfo->next_scanline;128if (num_lines > rows_left)129num_lines = rows_left;130131row_ctr = 0;132(*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, num_lines);133cinfo->next_scanline += row_ctr;134return row_ctr;135#else136ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);137return 0;138#endif139}140141142#if BITS_IN_JSAMPLE != 16143144/*145* Alternate entry point to write raw data.146* Processes exactly one iMCU row per call, unless suspended.147*/148149GLOBAL(JDIMENSION)150_jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data,151JDIMENSION num_lines)152{153JDIMENSION lines_per_iMCU_row;154155if (cinfo->data_precision != BITS_IN_JSAMPLE)156ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);157158if (cinfo->master->lossless)159ERREXIT(cinfo, JERR_NOTIMPL);160161if (cinfo->global_state != CSTATE_RAW_OK)162ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);163if (cinfo->next_scanline >= cinfo->image_height) {164WARNMS(cinfo, JWRN_TOO_MUCH_DATA);165return 0;166}167168/* Call progress monitor hook if present */169if (cinfo->progress != NULL) {170cinfo->progress->pass_counter = (long)cinfo->next_scanline;171cinfo->progress->pass_limit = (long)cinfo->image_height;172(*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo);173}174175/* Give master control module another chance if this is first call to176* _jpeg_write_raw_data. This lets output of the frame/scan headers be177* delayed so that application can write COM, etc, markers between178* jpeg_start_compress and _jpeg_write_raw_data.179*/180if (cinfo->master->call_pass_startup)181(*cinfo->master->pass_startup) (cinfo);182183/* Verify that at least one iMCU row has been passed. */184lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;185if (num_lines < lines_per_iMCU_row)186ERREXIT(cinfo, JERR_BUFFER_SIZE);187188/* Directly compress the row. */189if (!(*cinfo->coef->_compress_data) (cinfo, data)) {190/* If compressor did not consume the whole row, suspend processing. */191return 0;192}193194/* OK, we processed one iMCU row. */195cinfo->next_scanline += lines_per_iMCU_row;196return lines_per_iMCU_row;197}198199#endif /* BITS_IN_JSAMPLE != 16 */200201202