/* -*-C-*- ****************************************************************************** * * File: djpeg.c * RCS: $Header: /ImageMagick/delegates/fpx/jpeg/djpeg.c,v 1.2 2000/12/23 22:37:48 bfriesen Exp $ * Description: main module of JPEG decoder library. * Created: Fri Dec 4 11:04:22 1992 * Initial Source Release: Mon Jan 22 1996 * Language: C * Package: Hewlett-Packard JPEG Encoder/Decoder * * Copyright (c) 1999 Digital Imaging Group, Inc. * For conditions of distribution and use, see copyright notice * in Flashpix.h * ****************************************************************************** */ #include #include #include "jpegconf.h" #include "decoder.h" #include "dbuffer.h" #include "dectile.h" #include "djpeg.h" #include "fpxmem.h" void DB_Initdb_state(DB_STATE *db_state); /********************************** Local **********************************/ static int Read_Bytes_From_Memory(DB_STATE *db_state, unsigned char *buf, int nbytes) { int i; /* Check if there is enough data in the compressed-data buffer (inbuf) */ if (db_state->nbytes_left < nbytes) { nbytes = (db_state->nbytes_left <= 0) ? 0 : (int) db_state->nbytes_left; } for (i = nbytes; i > 0; i--) *buf++ = *db_state->db_inptr++; db_state->nbytes_left -= nbytes; return(nbytes); } static void Write_Rows_To_Memory(unsigned char *membuf, unsigned char *data, int nrows, int nbytes_per_row) { register int i,j; unsigned char *in_ptr,*out_ptr; in_ptr=data; out_ptr=membuf; for (i=nrows; i > 0 ;i--) for (j=nbytes_per_row; j > 0 ;j--) *out_ptr++ = *in_ptr++; } void DB_Initdb_state(DB_STATE *db_state) { /* just null out all pointers in db_state */ db_state->db_buf = NULL; db_state->db_ptr = NULL; db_state->db_supplied_bufs = NULL; db_state->db_supplied_ptr = NULL; db_state->db_outbuf = NULL; db_state->db_outptr = NULL; db_state->db_inptr = NULL; db_state->db_inbuf = NULL; db_state->db_MCUbuf = NULL; db_state->db_MCUptr = NULL; db_state->db_current_buf = NULL; db_state->db_current_buf2 = NULL; db_state->db_xtra_buf = NULL; db_state->db_row_bufs = NULL; } /* DB_Initdb_state() */ /********************************** EXPORT **********************************/ int JPEGDecodeTileInit( unsigned char *inbuf, size_t inbuf_size, TILE_DATA *tile_data, size_t *header_size, void *decoder ) { int method; int error_type; DB_STATE *db_state; DECODER_STRUCT *decodePtr = (DECODER_STRUCT *)decoder; int grayscale; method=0; grayscale = 0; if ((db_state= (DB_STATE *) FPX_malloc(sizeof(DB_STATE)))== NULL) { return(ERROR_MEM); } DB_Init(db_state, (int (*)(void *,void *,int))Read_Bytes_From_Memory, NULL, inbuf, inbuf_size, NULL, tile_data->iflag, 1); error_type = DE_Decode(db_state, decodePtr, method, grayscale, 1, &tile_data->width, &tile_data->height, &tile_data->components, tile_data->Hsamp, tile_data->Vsamp, tile_data->iflag ); *header_size = (size_t) DB_Processed_Bytes(db_state); DB_End(db_state); FPX_free(db_state); db_state = NULL; return(error_type); } int dJPEG_DecodeTileHeader(unsigned char *inbuf, size_t inbuf_size, void *decoder, int dct_method) { int method; int grayscale; int error_type; size_t byte_count; DB_STATE *db_state; DECODER_STRUCT *decodePtr = (DECODER_STRUCT *)decoder; int pass_num; size_t outbuf_size; int width,height,components; int iflag = 0; int Hsamp[4],Vsamp[4]; method=dct_method; if ((method != 0) && (method != 1)) method = 0; grayscale = 0; if ((db_state= (DB_STATE *) FPX_malloc(sizeof(DB_STATE)))== NULL) { return(ERROR_MEM); } db_state->db_buf = NULL; outbuf_size = inbuf_size; if ((db_state->db_MCUbuf = (unsigned int *)FPX_calloc(1, outbuf_size*sizeof(int)))==NULL) { return(ERROR_MEM); } db_state->db_MCUptr = db_state->db_MCUbuf; /* Interpret part of JPEG-Header */ pass_num = 1; DB_Init(db_state, (int(*)(void *, void *, int))Read_Bytes_From_Memory, NULL, inbuf, inbuf_size, NULL, iflag, pass_num); error_type = DE_Decode(db_state, decodePtr, method, grayscale, pass_num, &width, &height, &components, Hsamp,Vsamp, iflag ); if (error_type) { return(error_type); } byte_count = (size_t)DB_Processed_Bytes(db_state); if (db_state->db_MCUbuf != NULL) { FPX_free(db_state->db_MCUbuf); db_state->db_MCUbuf=NULL; } DB_End(db_state); FPX_free(db_state); db_state = NULL; return(error_type); } int dJPEG_DecodeTile(unsigned char *outbuf, size_t outbuf_size, unsigned char *inbuf, size_t inbuf_size, void *decoder, int parse_option, int dct_method) { int method; int grayscale; int error_type; size_t byte_count; DB_STATE *db_state; DECODER_STRUCT *decodePtr = (DECODER_STRUCT *)decoder; int pass_numb; TILE_DATA tile_data; int hdim[4], vdim[4]; /* jpeg interleave flag of 1 means it is interleaved. FlashPix interleave flag of 0 means it is interleaved! */ tile_data.iflag = (decodePtr->interleave_type == 0)? 1 : 0; tile_data.Hsamp = hdim; tile_data.Vsamp = vdim; if (parse_option == ENTROPY_AND_HEADER) { method=dct_method; if ((method != 0) && (method != 1) && (method !=2)) method = 0; grayscale = 0; if ((db_state= (DB_STATE *) FPX_malloc(sizeof(DB_STATE)))== NULL) { return(ERROR_MEM); } DB_Initdb_state(db_state); if ((db_state->db_MCUbuf = (unsigned int *)FPX_calloc(1, outbuf_size*sizeof(int)))==NULL) { return(ERROR_MEM); } db_state->db_MCUptr = db_state->db_MCUbuf; pass_numb = 2; DB_Init(db_state, (int(*)(void *, void *, int))Read_Bytes_From_Memory, (void(*)(void *, void *, int, int))Write_Rows_To_Memory, inbuf, inbuf_size, outbuf, tile_data.iflag, pass_numb); error_type = DE_Decode(db_state, decodePtr, method, grayscale, pass_numb, &tile_data.width, &tile_data.height, &tile_data.components, tile_data.Hsamp, tile_data.Vsamp, tile_data.iflag); if (error_type) { return(error_type); } byte_count = (size_t)DB_Processed_Bytes(db_state); if (db_state->db_MCUbuf != NULL) { FPX_free(db_state->db_MCUbuf); db_state->db_MCUbuf=NULL; } DB_End(db_state); FPX_free(db_state); db_state = NULL; } else { /* ENTROPY Data Only */ method=dct_method; if ((method != 0) && (method != 1) && (method !=2)) method = 0; grayscale = 0; if ((db_state= (DB_STATE *) FPX_malloc(sizeof(DB_STATE)))== NULL) { return(ERROR_MEM); } DB_Initdb_state(db_state); if ((db_state->db_MCUbuf = (unsigned int *)FPX_calloc(1, outbuf_size*sizeof(int)))==NULL) { return(ERROR_MEM); } db_state->db_MCUptr = db_state->db_MCUbuf; pass_numb = 0; DB_Init(db_state, (int(*)(void *, void *, int))Read_Bytes_From_Memory, (void(*)(void *, void *, int, int))Write_Rows_To_Memory, inbuf, inbuf_size, outbuf, tile_data.iflag, pass_numb); error_type = DE_Decode(db_state,decodePtr,method,grayscale, pass_numb, &tile_data.width,&tile_data.height, &tile_data.components, tile_data.Hsamp, tile_data.Vsamp, tile_data.iflag); if (error_type) { return(error_type); } byte_count = (size_t) DB_Processed_Bytes(db_state); if (db_state->db_MCUbuf != NULL) { FPX_free(db_state->db_MCUbuf); db_state->db_MCUbuf=NULL; } DB_End(db_state); FPX_free(db_state); db_state = NULL; } /* if ENTROPY_ONLY */ /* decide whether upsampling/color rotation are needed and apply them if needed. Grayscale and 2-channel images can never be downsampled or color-rotated. */ if ((decodePtr->num_channels != 1) && (decodePtr->num_channels != 2)) { if ( (decodePtr != NULL) && ((decodePtr->InternalUpsample) || (decodePtr->InternalColor))) error_type = dJPEG_UpsampleAndConvert(decodePtr, outbuf, outbuf_size); } return(error_type); }