File: jdapi.c

package info (click to toggle)
ucbmpeg 1r2-6
  • links: PTS
  • area: non-free
  • in suites: hamm, potato, slink
  • size: 9,504 kB
  • ctags: 7,643
  • sloc: ansic: 79,920; tcl: 2,985; perl: 313; asm: 284; makefile: 269; csh: 13
file content (358 lines) | stat: -rw-r--r-- 10,910 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
/*
 * jdapi.c
 *
 * Copyright (C) 1994, 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 application interface code for the decompression half of
 * the JPEG library.  Most of the routines intended to be called directly by
 * an application are in this file.  But also see jcomapi.c for routines
 * shared by compression and decompression.
 */

#include "jinclude.h"

#include "jpegint.h"


/*
 * Initialization of a JPEG decompression object.
 * The error manager must already be set up (in case memory manager fails).
 */

GLOBAL void
jpeg_create_decompress (j_decompress_ptr cinfo)
{
  int i;

  /* For debugging purposes, zero the whole master structure.
   * But error manager pointer is already there, so save and restore it.
   */
  {
    struct jpeg_error_mgr * err = cinfo->err;
    MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
    cinfo->err = err;
  }
  cinfo->is_decompressor = TRUE;

  /* Initialize a memory manager instance for this object */
  jinit_memory_mgr((j_common_ptr) cinfo);

  /* Zero out pointers to permanent structures. */
  cinfo->progress = NULL;
  cinfo->src = NULL;

  for (i = 0; i < NUM_QUANT_TBLS; i++)
    cinfo->quant_tbl_ptrs[i] = NULL;

  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    cinfo->dc_huff_tbl_ptrs[i] = NULL;
    cinfo->ac_huff_tbl_ptrs[i] = NULL;
  }

  cinfo->sample_range_limit = NULL;

  /* Initialize marker processor so application can override methods
   * for COM, APPn markers before calling jpeg_read_header.
   */
  cinfo->marker = NULL;
  jinit_marker_reader(cinfo);

  /* OK, I'm ready */
  cinfo->global_state = DSTATE_START;
}


/*
 * Destruction of a JPEG decompression object
 */

GLOBAL void
jpeg_destroy_decompress (j_decompress_ptr cinfo)
{
  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
}


/*
 * Set default decompression parameters.
 */

LOCAL void
default_decompress_parms (j_decompress_ptr cinfo)
{
  /* Guess the input colorspace, and set output colorspace accordingly. */
  /* (Wish JPEG committee had provided a real way to specify this...) */
  /* Note application may override our guesses. */
  cinfo->want_raw_output = FALSE;
  switch (cinfo->num_components) {
  case 1:
    cinfo->jpeg_color_space = JCS_GRAYSCALE;
    cinfo->out_color_space = JCS_GRAYSCALE;
    break;
    
  case 3:
    if (cinfo->saw_JFIF_marker) {
      cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
    } else if (cinfo->saw_Adobe_marker) {
      switch (cinfo->Adobe_transform) {
      case 0:
	cinfo->jpeg_color_space = JCS_RGB;
	break;
      case 1:
	cinfo->jpeg_color_space = JCS_YCbCr;
	break;
      default:
	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
	break;
      }
    } else {
      /* Saw no special markers, try to guess from the component IDs */
      int cid0 = cinfo->comp_info[0].component_id;
      int cid1 = cinfo->comp_info[1].component_id;
      int cid2 = cinfo->comp_info[2].component_id;

      if (cid0 == 1 && cid1 == 2 && cid2 == 3)
	cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
      else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
	cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
      else {
	TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
      }
    }
    /* Always guess RGB is proper output colorspace. */
    cinfo->out_color_space = JCS_RGB;
    break;
    
  case 4:
    if (cinfo->saw_Adobe_marker) {
      switch (cinfo->Adobe_transform) {
      case 0:
	cinfo->jpeg_color_space = JCS_CMYK;
	break;
      case 2:
	cinfo->jpeg_color_space = JCS_YCCK;
	break;
      default:
	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
	cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
	break;
      }
    } else {
      /* No special markers, assume straight CMYK. */
      cinfo->jpeg_color_space = JCS_CMYK;
    }
    cinfo->out_color_space = JCS_CMYK;
    break;
    
  default:
    cinfo->jpeg_color_space = JCS_UNKNOWN;
    cinfo->out_color_space = JCS_UNKNOWN;
    break;
  }

  /* Set defaults for other decompression parameters. */
  cinfo->scale_num = 1;		/* 1:1 scaling */
  cinfo->scale_denom = 1;
  cinfo->output_gamma = 1.0;
  cinfo->quantize_colors = FALSE;
  /* We set these in case application only sets quantize_colors. */
  cinfo->two_pass_quantize = TRUE;
  cinfo->use_dithering = TRUE;
  cinfo->desired_number_of_colors = 256;
  cinfo->do_block_smoothing = FALSE;
  cinfo->do_fancy_upsampling = TRUE;
  cinfo->colormap = NULL;
}


/*
 * Decompression startup: read start of JPEG datastream to see what's there.
 * Need only initialize JPEG object and supply a data source before calling.
 *
 * This routine will read as far as the first SOS marker (ie, actual start of
 * compressed data), and will save all tables and parameters in the JPEG
 * object.  It will also initialize the decompression parameters to default
 * values, and finally return JPEG_HEADER_OK.  On return, the application may
 * adjust the decompression parameters and then call jpeg_start_decompress.
 * (Or, if the application only wanted to determine the image parameters,
 * the data need not be decompressed.  In that case, call jpeg_abort or
 * jpeg_destroy to release any temporary space.)
 * If an abbreviated (tables only) datastream is presented, the routine will
 * return JPEG_HEADER_TABLES_ONLY upon reaching EOI.  The application may then
 * re-use the JPEG object to read the abbreviated image datastream(s).
 * It is unnecessary (but OK) to call jpeg_abort in this case.
 * The JPEG_SUSPENDED return code only occurs if the data source module
 * requests suspension of the decompressor.  In this case the application
 * should load more source data and then re-call jpeg_read_header to resume
 * processing.
 * If a non-suspending data source is used and require_image is TRUE, then the
 * return code need not be inspected since only JPEG_HEADER_OK is possible.
 */

GLOBAL int
jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
{
  int retcode;

  if (cinfo->global_state == DSTATE_START) {
    /* First-time actions: reset appropriate modules */
    (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
    (*cinfo->marker->reset_marker_reader) (cinfo);
    (*cinfo->src->init_source) (cinfo);
    cinfo->global_state = DSTATE_INHEADER;
  } else if (cinfo->global_state != DSTATE_INHEADER) {
    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  }

  retcode = (*cinfo->marker->read_markers) (cinfo);

  switch (retcode) {
  case JPEG_HEADER_OK:		/* Found SOS, prepare to decompress */
    /* Set up default parameters based on header data */
    default_decompress_parms(cinfo);
    /* Set global state: ready for start_decompress */
    cinfo->global_state = DSTATE_READY;
    break;

  case JPEG_HEADER_TABLES_ONLY:	/* Found EOI before any SOS */
    if (cinfo->marker->saw_SOF)
      ERREXIT(cinfo, JERR_SOF_NO_SOS);
    if (require_image)		/* Complain if application wants an image */
      ERREXIT(cinfo, JERR_NO_IMAGE);
    /* We need not do any cleanup since only permanent storage (for DQT, DHT)
     * has been allocated.
     */
    /* Set global state: ready for a new datastream */
    cinfo->global_state = DSTATE_START;
    break;

  case JPEG_SUSPENDED:		/* Had to suspend before end of headers */
    /* no work */
    break;
  }

  return retcode;
}


/*
 * Decompression initialization.
 * jpeg_read_header must be completed before calling this.
 *
 * If a multipass operating mode was selected, this will do all but the
 * last pass, and thus may take a great deal of time.
 */

GLOBAL void
jpeg_start_decompress (j_decompress_ptr cinfo)
{
  if (cinfo->global_state != DSTATE_READY)
    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  /* Perform master selection of active modules */
  jinit_master_decompress(cinfo);
  /* Do all but the final (output) pass, and set up for that one. */
  for (;;) {
    (*cinfo->master->prepare_for_pass) (cinfo);
    if (cinfo->master->is_last_pass)
      break;
    /* Drive pass here??? */
    /* Terminate pass here??? */
  }
  /* Ready for application to drive last pass through jpeg_read_scanlines */
  cinfo->output_scanline = 0;
  cinfo->global_state = DSTATE_SCANNING;
}


/*
 * Read some scanlines of data from the JPEG decompressor.
 *
 * The return value will be the number of lines actually read.
 * This may be less than the number requested in several cases,
 * including bottom of image, data source suspension, and operating
 * modes that emit multiple scanlines at a time.
 */

GLOBAL JDIMENSION
jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
		     JDIMENSION max_lines)
{
  JDIMENSION row_ctr;

  if (cinfo->global_state != DSTATE_SCANNING)
    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  row_ctr = 0;
  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
  cinfo->output_scanline += row_ctr;
  return row_ctr;
}
GLOBAL JDIMENSION
jpeg_read_raw_scanlines(j_decompress_ptr cinfo, JSAMPIMAGE scanarray,
                         JDIMENSION max_lines)
{
 JDIMENSION row_ctr;


 if (cinfo->global_state != DSTATE_SCANNING)
   ERREXIT1(cinfo,JERR_BAD_STATE,cinfo->global_state);
 row_ctr =0;
 (*cinfo->main->process_data)(cinfo,scanarray,&row_ctr,max_lines);
  

 cinfo->output_scanline += row_ctr;

 return row_ctr;
}

/*
 * Finish JPEG decompression.
 *
 * This will normally just verify the file trailer and release temp storage.
 *
 * Returns FALSE if suspended.  The return value need be inspected only if
 * a suspending data source is used.
 */

GLOBAL boolean
jpeg_finish_decompress (j_decompress_ptr cinfo)
{
  if (cinfo->global_state == DSTATE_SCANNING &&
      cinfo->output_scanline == cinfo->output_height) {
    /* Terminate final pass */
    (*cinfo->main->finish_pass) (cinfo);
    cinfo->global_state = DSTATE_STOPPING;
  } else if (cinfo->global_state != DSTATE_STOPPING) {
    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  }
  /* Check for EOI in source file */
  switch ((*cinfo->marker->read_markers) (cinfo)) {
  case JPEG_HEADER_OK:		/* Found SOS!? */
    ERREXIT(cinfo, JERR_EOI_EXPECTED);
    break;
  case JPEG_HEADER_TABLES_ONLY:	/* Found EOI, A-OK */
    break;
  case JPEG_SUSPENDED:		/* Suspend, come back later */
    return FALSE;
  }
  /* Do final cleanup ??? */
  (*cinfo->src->term_source) (cinfo);
  /* We can use jpeg_abort to release memory and reset global_state */
  jpeg_abort((j_common_ptr) cinfo);
  return TRUE;
}


/*
 * Abort processing of a JPEG decompression operation,
 * but don't destroy the object itself.
 */

GLOBAL void
jpeg_abort_decompress (j_decompress_ptr cinfo)
{
  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
}