Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

527 lines
16 KiB

/*
* jdmaster.c
*
* Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains the main control for the JPEG decompressor.
* The system-dependent (user interface) code should call jpeg_decompress()
* after doing appropriate setup of the decompress_info_struct parameter.
*/
#include "windows.h"
#include "jinclude.h"
#include "jpeg_win.h"
#include <setjmp.h>
#include "taskdata.h"
#include "jglobstr.h"
// 9505.02 jar
#define LOCAL static /* a function used only in its module */
// 9509.27 jar define the static memory token!
DWORD dwTlsIndex;
external_methods_ptr emethods;
// (HJG moved to lpGlobStruct) extern boolean first_strip;
// (HJG moved to lpGlobStruct) jmp_buf setjmp_buffer;
// (HJG moved to lpGlobStruct) int error_number, all_done;
// (HJG moved to lpGlobStruct) int image_components;
// (HJG moved to lpGlobStruct) int rows_read_decmp, ret_pipe_de, start_decmp, rows_in_buf_decmp;
// (HJG moved to lpGlobStruct) char FAR *cmp_buf_ptr, FAR *decmp_buf_ptr, FAR *decmp_buf_ptr_init;
// (HJG moved to lpGlobStruct) char FAR *cmp_buf_ptr_init;
// HERE
// (HJG moved to lpGlobStruct) int rows_in_buf_decmp; /* No. of rows moved to outpu buffer */
// (HJG moved to lpGlobStruct) int lines_decmp; /* Decompress Buffer Size */
// (HJG moved to lpGlobStruct) int error_write_decmp;
// (HJG moved to lpGlobStruct) char FAR *header_ptr;
// (HJG moved to lpGlobStruct) int header_length, old_jpeg;
// (HJG moved to lpGlobStruct) char FAR *lp_sos;
//int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg, WORD cbHeapSize,
// LPSTR lpszCmdLine);
//
//int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg, WORD cbHeapSize,
// LPSTR lpszCmdLine)
//{
//// LockData (0);
// return(1);
//}
//
//
//
//
//VOID FAR PASCAL WEP(int nParameter);
//VOID FAR PASCAL WEP(int nParameter)
//{
// return;
//}
//
//
//************************************************************************
//
// DllMain this replaces the whole mess above!!! ( Windows95)
//
//************************************************************************
int CALLBACK DllMain( HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
LPOI_JPEG_GLOBALS_STRUCT lpJCmpGlobal;
BOOL fIgnore;
switch ( dwReason)
{
// first the attachment stuff
case DLL_PROCESS_ATTACH:
// allocate our Tls stuff
if ( (dwTlsIndex = TlsAlloc()) == 0xffffffff)
{
return FALSE;
}
// there is NO "break" between this case and the next
case DLL_THREAD_ATTACH:
// init the Tls index for this thread
lpJCmpGlobal = ( LPOI_JPEG_GLOBALS_STRUCT)LocalAlloc( LPTR,
sizeof( OI_JPEG_GLOBALS_STRUCT));
if ( lpJCmpGlobal != NULL)
{
fIgnore = TlsSetValue( dwTlsIndex, lpJCmpGlobal);
}
break;
// now, de-attachment stuff, breaking up is hard to do!
case DLL_THREAD_DETACH:
// release Tls for this thread
lpJCmpGlobal = ( LPOI_JPEG_GLOBALS_STRUCT)TlsGetValue(dwTlsIndex);
if ( lpJCmpGlobal != NULL)
{
LocalFree( (HLOCAL) lpJCmpGlobal);
}
break;
case DLL_PROCESS_DETACH:
// release Tls stuff
lpJCmpGlobal = ( LPOI_JPEG_GLOBALS_STRUCT)TlsGetValue(dwTlsIndex);
if ( lpJCmpGlobal != NULL)
{
LocalFree( (HLOCAL) lpJCmpGlobal);
}
// release Tls index
TlsFree( dwTlsIndex);
break;
}
return TRUE;
}
// 9504.20 jar no exprt tariff!
//VOID FAR PASCAL _export jpeg_decmp_init (int width, int height, int components, int color_space,
// int data_precision, decompress_info_ptr dcinfo)
VOID FAR PASCAL jpeg_decmp_init (int width, int height, int components,
int color_space, int data_precision,
decompress_info_ptr dcinfo)
/* Initialization for image parameters */
{
// 9509.21 jar use Thread Local Storage to manage JPEG Globals
LPOI_JPEG_GLOBALS_STRUCT lpGlobStruct;
lpGlobStruct = ( LPOI_JPEG_GLOBALS_STRUCT)TlsGetValue( dwTlsIndex);
// 9509.21 jar if null, we'll alloc and set for this thread
if ( lpGlobStruct == NULL)
{
lpGlobStruct = ( LPOI_JPEG_GLOBALS_STRUCT)LocalAlloc( LPTR,
sizeof( OI_JPEG_GLOBALS_STRUCT));
if (lpGlobStruct != NULL)
{
TlsSetValue( dwTlsIndex, lpGlobStruct);
}
}
dcinfo->image_width = width;
dcinfo->image_height = height;
/* dcinfo->input_components = components; */
dcinfo->out_color_space = color_space;
dcinfo->data_precision = data_precision;
dcinfo->color_out_comps = components;
dcinfo->final_out_comps = components;
dcinfo->quantize_colors = FALSE;
lpGlobStruct->all_done = 0;
lpGlobStruct->rows_read_decmp = 0;
lpGlobStruct->image_components = components;
lpGlobStruct->start_decmp = 1;
lpGlobStruct->ret_pipe_de = 0;
lpGlobStruct->rows_in_buf_decmp = 0;
}
METHODDEF void
output_term (decompress_info_ptr cinfo)
{
}
METHODDEF int
put_pixel_rows (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
/* Write some rows of output data */
{
/* This example shows how you might write full-color RGB data (3 components)
* to an output file in which the data is stored 3 bytes per pixel.
*/
// register FILE * outfile = cinfo->output_file;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
register int row;
// 9509.21 jar use Thread Local Storage to manage JPEG Globals
int result;
LPOI_JPEG_GLOBALS_STRUCT lpGlobStruct;
lpGlobStruct = ( LPOI_JPEG_GLOBALS_STRUCT)TlsGetValue( dwTlsIndex);
// 9509.21 jar if null, we'll alloc and set for this thread
if ( lpGlobStruct == NULL)
{
lpGlobStruct = ( LPOI_JPEG_GLOBALS_STRUCT)LocalAlloc( LPTR,
sizeof( OI_JPEG_GLOBALS_STRUCT));
if (lpGlobStruct != NULL)
{
TlsSetValue( dwTlsIndex, lpGlobStruct);
}
}
for (row = 0; row < num_rows; row++)
{
ptr0 = pixel_data[0][row];
if (lpGlobStruct->image_components != 1)
{
ptr1 = pixel_data[1][row];
ptr2 = pixel_data[2][row];
}
for (col = 0; col < cinfo->image_width; col++)
{
*lpGlobStruct->decmp_buf_ptr = *ptr0; /*Red */
lpGlobStruct->decmp_buf_ptr++;
ptr0++;
if (lpGlobStruct->image_components != 1)
{
*lpGlobStruct->decmp_buf_ptr = *ptr1; /*Green */
lpGlobStruct->decmp_buf_ptr++;
ptr1++;
*lpGlobStruct->decmp_buf_ptr = *ptr2; /*Blue */
lpGlobStruct->decmp_buf_ptr++;
ptr2++;
}
/* putc(GETJSAMPLE(*ptr0), outfile); Red
ptr0++;
putc(GETJSAMPLE(*ptr1), outfile); Green
ptr1++;
putc(GETJSAMPLE(*ptr2), outfile); Blue
ptr2++; */
}
lpGlobStruct->rows_in_buf_decmp++;
if (lpGlobStruct->rows_in_buf_decmp >= lpGlobStruct->lines_decmp)
{
lpGlobStruct->error_write_decmp = (*cinfo->methods->output_decmp_data) (lpGlobStruct->rows_in_buf_decmp);
if (lpGlobStruct->error_write_decmp > 0)
{
result = lpGlobStruct->error_write_decmp;
return (result);
}
lpGlobStruct->rows_in_buf_decmp = 0;
lpGlobStruct->decmp_buf_ptr = lpGlobStruct->decmp_buf_ptr_init;
}
}
if (lpGlobStruct->all_done)
{
if (lpGlobStruct->rows_in_buf_decmp > 0)
lpGlobStruct->error_write_decmp = (*cinfo->methods->output_decmp_data) (lpGlobStruct->rows_in_buf_decmp);
if (lpGlobStruct->error_write_decmp > 0)
{
result = lpGlobStruct->error_write_decmp;
return(result);
}
lpGlobStruct->rows_in_buf_decmp = 0;
lpGlobStruct->decmp_buf_ptr = lpGlobStruct->decmp_buf_ptr_init;
}
return (0);
}
METHODDEF void
d_ui_method_selection (decompress_info_ptr cinfo)
{
/* if grayscale input, force grayscale output; */
/* else leave the output colorspace as set by main routine. */
if (cinfo->jpeg_color_space == CS_GRAYSCALE)
cinfo->out_color_space = CS_GRAYSCALE;
/* select output routines */
/* cinfo->methods->output_init = output_init; */
/* cinfo->methods->put_color_map = put_color_map; */
cinfo->methods->put_pixel_rows = put_pixel_rows;
cinfo->methods->output_term = output_term;
}
METHODDEF void
d_per_scan_method_selection (decompress_info_ptr cinfo)
/* Central point for per-scan method selection */
{
/* MCU disassembly */
jseldmcu(cinfo);
/* Upsampling of pixels */
jselupsample(cinfo);
}
LOCAL void
d_initial_method_selection (decompress_info_ptr cinfo)
/* Central point for initial method selection (after reading file header) */
{
/* JPEG file scanning method selection is already done. */
/* So is output file format selection (both are done by user interface). */
/* Entropy decoding: either Huffman or arithmetic coding. */
#ifdef D_ARITH_CODING_SUPPORTED
jseldarithmetic(cinfo);
#else
if (cinfo->arith_code) {
ERREXIT(cinfo->emethods, "Arithmetic coding not supported");
}
#endif
jseldhuffman(cinfo);
/* Cross-block smoothing */
#ifdef BLOCK_SMOOTHING_SUPPORTED
jselbsmooth(cinfo);
#else
cinfo->do_block_smoothing = FALSE;
#endif
/* Gamma and color space conversion */
jseldcolor(cinfo);
/* Color quantization selection rules */
#ifdef QUANT_1PASS_SUPPORTED
#ifdef QUANT_2PASS_SUPPORTED
/* We have both, check for conditions in which 1-pass should be used */
if (cinfo->num_components != 3 || cinfo->jpeg_color_space != CS_YCbCr)
cinfo->two_pass_quantize = FALSE; /* 2-pass only handles YCbCr input */
if (cinfo->out_color_space == CS_GRAYSCALE)
cinfo->two_pass_quantize = FALSE; /* Should use 1-pass for grayscale out */
#else /* not QUANT_2PASS_SUPPORTED */
cinfo->two_pass_quantize = FALSE; /* only have 1-pass */
#endif
#else /* not QUANT_1PASS_SUPPORTED */
#ifdef QUANT_2PASS_SUPPORTED
cinfo->two_pass_quantize = TRUE; /* only have 2-pass */
#else /* not QUANT_2PASS_SUPPORTED */
if (cinfo->quantize_colors) {
ERREXIT(cinfo->emethods, "Color quantization was not compiled");
}
#endif
#endif
#ifdef QUANT_1PASS_SUPPORTED
jsel1quantize(cinfo);
#endif
#ifdef QUANT_2PASS_SUPPORTED
jsel2quantize(cinfo);
#endif
/* Pipeline control */
jseldpipeline(cinfo);
/* Overall control (that's me!) */
cinfo->methods->d_per_scan_method_selection = d_per_scan_method_selection;
}
LOCAL void
initial_setup (decompress_info_ptr cinfo)
/* Do computations that are needed before initial method selection */
{
short ci;
jpeg_component_info FAR *compptr;
/* Compute maximum sampling factors; check factor validity */
cinfo->max_h_samp_factor = 1;
cinfo->max_v_samp_factor = 1;
for (ci = 0; ci < cinfo->num_components; ci++) {
compptr = &cinfo->comp_info[ci];
if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
ERREXIT(cinfo->emethods, "Bogus sampling factors");
cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
compptr->h_samp_factor);
cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
compptr->v_samp_factor);
}
/* Compute logical downsampled dimensions of components */
for (ci = 0; ci < cinfo->num_components; ci++)
{
compptr = &cinfo->comp_info[ci];
compptr->true_comp_width = (cinfo->image_width * compptr->h_samp_factor
+ cinfo->max_h_samp_factor - 1)
/ cinfo->max_h_samp_factor;
compptr->true_comp_height = (cinfo->image_height * compptr->v_samp_factor
+ cinfo->max_v_samp_factor - 1)
/ cinfo->max_v_samp_factor;
}
}
/*
* This is the main entry point to the JPEG decompressor.
*/
// 9504.20 jar no exprt tariff!
//GLOBAL int FAR PASCAL _export
//jpeg_decmp( decompress_info_ptr cinfo, int bytes_read,
// char far *cmpress_ptr, char far *decmpress_ptr,
// int no_lines_decompressed, char far *pheader, int
// lheader, char far *p_sos)
GLOBAL int FAR PASCAL jpeg_decmp( decompress_info_ptr cinfo, int bytes_read,
char far *cmpress_ptr,
char far *decmpress_ptr,
int no_lines_decompressed, char far *pheader,
int lheader, char far *p_sos)
{
int error_write;
int no_mcu;
int header_count = 0;
// 9509.21 jar use Thread Local Storage to manage JPEG Globals
int result;
LPOI_JPEG_GLOBALS_STRUCT lpGlobStruct;
lpGlobStruct = ( LPOI_JPEG_GLOBALS_STRUCT)TlsGetValue( dwTlsIndex);
// 9509.21 jar if null, we'll alloc and set for this thread
if ( lpGlobStruct == NULL)
{
lpGlobStruct = ( LPOI_JPEG_GLOBALS_STRUCT)LocalAlloc( LPTR,
sizeof( OI_JPEG_GLOBALS_STRUCT));
if (lpGlobStruct != NULL)
{
TlsSetValue( dwTlsIndex, lpGlobStruct);
}
}
if (( *cmpress_ptr == (char)0xff) && ( *(cmpress_ptr+1) == (char)0xd8 ))
{
pheader = cmpress_ptr;
lpGlobStruct->old_jpeg = 1;
while (!((*cmpress_ptr == (char)0xff)&&(*(cmpress_ptr+1) == (char)0xda)))
{
header_count++;
cmpress_ptr++;
}
lheader = header_count;
lpGlobStruct->first_strip = FALSE;
lpGlobStruct->header_ptr = pheader;
/* header_length = lheader; */
/* Check for gray-scale images and fix them if present */
if ( cinfo->final_out_comps == 1)
{
while (!((*pheader == (char)0xd9)&&(*(pheader+1)==(char)0xda)))
pheader++;
*(pheader+2) = (char)0xe1;
*(pheader+3) = (char)0xe2;
while (!((*pheader == (char)0xff)&&(*(pheader+1)==(char)0xdd)))
{
pheader++;
if (pheader > cmpress_ptr)
break;
}
if (pheader < cmpress_ptr)
{
no_mcu = (int) (cinfo->image_width + 7) /8;
*(pheader+4) = (char) HIBYTE(no_mcu);
*(pheader+5) = (char) LOBYTE(no_mcu);
}
}
pheader = lpGlobStruct->header_ptr; /* Restore it to its proper value */
bytes_read -= lpGlobStruct->header_length;
}
lpGlobStruct->header_ptr = pheader;
lpGlobStruct->header_length = lheader;
lpGlobStruct->lp_sos = p_sos;
/* Init pass counts to 0 --- total_passes is adjusted in method selection */
cinfo->total_passes = 0;
cinfo->completed_passes = 0;
jselerror(cinfo->emethods);
if (setjmp(lpGlobStruct->setjmp_buffer))
{
if (lpGlobStruct->error_number < 10)
{
if (lpGlobStruct->error_number != 3)
lpGlobStruct->error_number = 1;
}
result =lpGlobStruct->error_number;
return (result);
}
jselmemmgr(cinfo->emethods);
cinfo->methods->d_ui_method_selection = d_ui_method_selection;
lpGlobStruct->cmp_buf_ptr = cmpress_ptr;
lpGlobStruct->cmp_buf_ptr_init = lpGlobStruct->cmp_buf_ptr;
lpGlobStruct->decmp_buf_ptr = decmpress_ptr;
lpGlobStruct->decmp_buf_ptr_init = decmpress_ptr;
lpGlobStruct->lines_decmp = no_lines_decompressed;
j_d_defaults(cinfo, FALSE);
cinfo->bytes_in_buffer = bytes_read;
cinfo->input_buffer = cmpress_ptr;
cinfo->next_input_byte = cmpress_ptr;
jselrtiff(cinfo);
/* Read the JPEG file header markers; everything up through the first SOS
* marker is read now. NOTE: the user interface must have initialized the
* read_file_header method pointer (eg, by calling jselrjfif or jselrtiff).
* The other file reading methods (read_scan_header etc.) were probably
* set at the same time, but could be set up by read_file_header itself.
*/
(*cinfo->methods->read_file_header) (cinfo);
if (! ((*cinfo->methods->read_scan_header) (cinfo)))
ERREXIT(cinfo->emethods, "Empty JPEG file");
/* Give UI a chance to adjust decompression parameters and select */
/* output file format based on info from file header. */
(*cinfo->methods->d_ui_method_selection) (cinfo);
/* Now select methods for decompression steps. */
initial_setup(cinfo);
d_initial_method_selection(cinfo);
/* Initialize the output file & other modules as needed */
/* (modules needing per-scan init are called by pipeline controller) */
/* The foll. initialization has been removed in our release and moved at
the application level */
/* (*cinfo->methods->output_init) (cinfo); */
(*cinfo->methods->colorout_init) (cinfo);
if (cinfo->quantize_colors)
(*cinfo->methods->color_quant_init) (cinfo);
/* And let the pipeline controller do the rest. */
error_write = (*cinfo->methods->d_pipeline_controller) (cinfo);
if (error_write > 0)
{
return(error_write);
}
/* Finish output file, release working storage, etc */
if (cinfo->quantize_colors)
(*cinfo->methods->color_quant_term) (cinfo);
(*cinfo->methods->colorout_term) (cinfo);
(*cinfo->methods->output_term) (cinfo);
(*cinfo->methods->read_file_trailer) (cinfo);
(*cinfo->emethods->free_all) ();
return(0);
}