/*1* jcapistd.c2*3* Copyright (C) 1994-1996, Thomas G. Lane.4* Modified 2013 by Guido Vollbeding.5* This file is part of the Independent JPEG Group's software.6* For conditions of distribution and use, see the accompanying README file.7*8* This file contains application interface code for the compression half9* of the JPEG library. These are the "standard" API routines that are10* used in the normal full-compression case. They are not used by a11* transcoding-only application. Note that if an application links in12* jpeg_start_compress, it will end up linking in the entire compressor.13* We thus must separate this file from jcapimin.c to avoid linking the14* whole compression library into a transcoder.15*/1617#define JPEG_INTERNALS18#include "jinclude.h"19#include "jpeglib.h"202122/*23* Compression initialization.24* Before calling this, all parameters and a data destination must be set up.25*26* We require a write_all_tables parameter as a failsafe check when writing27* multiple datastreams from the same compression object. Since prior runs28* will have left all the tables marked sent_table=TRUE, a subsequent run29* would emit an abbreviated stream (no tables) by default. This may be what30* is wanted, but for safety's sake it should not be the default behavior:31* programmers should have to make a deliberate choice to emit abbreviated32* images. Therefore the documentation and examples should encourage people33* to pass write_all_tables=TRUE; then it will take active thought to do the34* wrong thing.35*/3637GLOBAL(void)38jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)39{40if (cinfo->global_state != CSTATE_START)41ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);4243if (write_all_tables)44jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */4546/* (Re)initialize error mgr and destination modules */47(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);48(*cinfo->dest->init_destination) (cinfo);49/* Perform master selection of active modules */50jinit_compress_master(cinfo);51/* Set up for the first pass */52(*cinfo->master->prepare_for_pass) (cinfo);53/* Ready for application to drive first pass through jpeg_write_scanlines54* or jpeg_write_raw_data.55*/56cinfo->next_scanline = 0;57cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);58}596061/*62* Write some scanlines of data to the JPEG compressor.63*64* The return value will be the number of lines actually written.65* This should be less than the supplied num_lines only in case that66* the data destination module has requested suspension of the compressor,67* or if more than image_height scanlines are passed in.68*69* Note: we warn about excess calls to jpeg_write_scanlines() since70* this likely signals an application programmer error. However,71* excess scanlines passed in the last valid call are *silently* ignored,72* so that the application need not adjust num_lines for end-of-image73* when using a multiple-scanline buffer.74*/7576GLOBAL(JDIMENSION)77jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,78JDIMENSION num_lines)79{80JDIMENSION row_ctr, rows_left;8182if (cinfo->global_state != CSTATE_SCANNING)83ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);84if (cinfo->next_scanline >= cinfo->image_height)85WARNMS(cinfo, JWRN_TOO_MUCH_DATA);8687/* Call progress monitor hook if present */88if (cinfo->progress != NULL) {89cinfo->progress->pass_counter = (long) cinfo->next_scanline;90cinfo->progress->pass_limit = (long) cinfo->image_height;91(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);92}9394/* Give master control module another chance if this is first call to95* jpeg_write_scanlines. This lets output of the frame/scan headers be96* delayed so that application can write COM, etc, markers between97* jpeg_start_compress and jpeg_write_scanlines.98*/99if (cinfo->master->call_pass_startup)100(*cinfo->master->pass_startup) (cinfo);101102/* Ignore any extra scanlines at bottom of image. */103rows_left = cinfo->image_height - cinfo->next_scanline;104if (num_lines > rows_left)105num_lines = rows_left;106107row_ctr = 0;108(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);109cinfo->next_scanline += row_ctr;110return row_ctr;111}112113114/*115* Alternate entry point to write raw data.116* Processes exactly one iMCU row per call, unless suspended.117*/118119GLOBAL(JDIMENSION)120jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,121JDIMENSION num_lines)122{123JDIMENSION lines_per_iMCU_row;124125if (cinfo->global_state != CSTATE_RAW_OK)126ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);127if (cinfo->next_scanline >= cinfo->image_height) {128WARNMS(cinfo, JWRN_TOO_MUCH_DATA);129return 0;130}131132/* Call progress monitor hook if present */133if (cinfo->progress != NULL) {134cinfo->progress->pass_counter = (long) cinfo->next_scanline;135cinfo->progress->pass_limit = (long) cinfo->image_height;136(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);137}138139/* Give master control module another chance if this is first call to140* jpeg_write_raw_data. This lets output of the frame/scan headers be141* delayed so that application can write COM, etc, markers between142* jpeg_start_compress and jpeg_write_raw_data.143*/144if (cinfo->master->call_pass_startup)145(*cinfo->master->pass_startup) (cinfo);146147/* Verify that at least one iMCU row has been passed. */148lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_v_scaled_size;149if (num_lines < lines_per_iMCU_row)150ERREXIT(cinfo, JERR_BUFFER_SIZE);151152/* Directly compress the row. */153if (! (*cinfo->coef->compress_data) (cinfo, data)) {154/* If compressor did not consume the whole row, suspend processing. */155return 0;156}157158/* OK, we processed one iMCU row. */159cinfo->next_scanline += lines_per_iMCU_row;160return lines_per_iMCU_row;161}162163164