~dcow90/myro-c++/extern-c

« back to all changes in this revision

Viewing changes to jpeg/jctrans.c

  • Committer: John Hoare
  • Date: 2011-05-15 12:49:43 UTC
  • mfrom: (81.1.19 cimg-backend)
  • Revision ID: john@johnami.com-20110515124943-2twlnindkrt1zeo9
Changed backend to CImg, added Graphics Library, added a rudimentary joystick control program using the Drawing Library. 

Put in our own version of libjpeg so we no longer rely on the system's libjpeg. 

Picture object's show() method is no longer necessarily a blocking call now. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * jctrans.c
 
3
 *
 
4
 * Copyright (C) 1995-1998, Thomas G. Lane.
 
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 library routines for transcoding compression,
 
9
 * that is, writing raw DCT coefficient arrays to an output JPEG file.
 
10
 * The routines in jcapimin.c will also be needed by a transcoder.
 
11
 */
 
12
 
 
13
#define JPEG_INTERNALS
 
14
#include "myrojinclude.h"
 
15
#include "myrojpeglib.h"
 
16
 
 
17
 
 
18
/* Forward declarations */
 
19
LOCAL(void) transencode_master_selection
 
20
        JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
 
21
LOCAL(void) transencode_coef_controller
 
22
        JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
 
23
 
 
24
 
 
25
/*
 
26
 * Compression initialization for writing raw-coefficient data.
 
27
 * Before calling this, all parameters and a data destination must be set up.
 
28
 * Call jpeg_finish_compress() to actually write the data.
 
29
 *
 
30
 * The number of passed virtual arrays must match cinfo->num_components.
 
31
 * Note that the virtual arrays need not be filled or even realized at
 
32
 * the time write_coefficients is called; indeed, if the virtual arrays
 
33
 * were requested from this compression object's memory manager, they
 
34
 * typically will be realized during this routine and filled afterwards.
 
35
 */
 
36
 
 
37
GLOBAL(void)
 
38
jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
 
39
{
 
40
  if (cinfo->global_state != CSTATE_START)
 
41
    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 
42
  /* Mark all tables to be written */
 
43
  jpeg_suppress_tables(cinfo, FALSE);
 
44
  /* (Re)initialize error mgr and destination modules */
 
45
  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
 
46
  (*cinfo->dest->init_destination) (cinfo);
 
47
  /* Perform master selection of active modules */
 
48
  transencode_master_selection(cinfo, coef_arrays);
 
49
  /* Wait for jpeg_finish_compress() call */
 
50
  cinfo->next_scanline = 0;     /* so jpeg_write_marker works */
 
51
  cinfo->global_state = CSTATE_WRCOEFS;
 
52
}
 
53
 
 
54
 
 
55
/*
 
56
 * Initialize the compression object with default parameters,
 
57
 * then copy from the source object all parameters needed for lossless
 
58
 * transcoding.  Parameters that can be varied without loss (such as
 
59
 * scan script and Huffman optimization) are left in their default states.
 
60
 */
 
61
 
 
62
GLOBAL(void)
 
63
jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
 
64
                               j_compress_ptr dstinfo)
 
65
{
 
66
  JQUANT_TBL ** qtblptr;
 
67
  jpeg_component_info *incomp, *outcomp;
 
68
  JQUANT_TBL *c_quant, *slot_quant;
 
69
  int tblno, ci, coefi;
 
70
 
 
71
  /* Safety check to ensure start_compress not called yet. */
 
72
  if (dstinfo->global_state != CSTATE_START)
 
73
    ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
 
74
  /* Copy fundamental image dimensions */
 
75
  dstinfo->image_width = srcinfo->image_width;
 
76
  dstinfo->image_height = srcinfo->image_height;
 
77
  dstinfo->input_components = srcinfo->num_components;
 
78
  dstinfo->in_color_space = srcinfo->jpeg_color_space;
 
79
  /* Initialize all parameters to default values */
 
80
  jpeg_set_defaults(dstinfo);
 
81
  /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
 
82
   * Fix it to get the right header markers for the image colorspace.
 
83
   */
 
84
  jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
 
85
  dstinfo->data_precision = srcinfo->data_precision;
 
86
  dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
 
87
  /* Copy the source's quantization tables. */
 
88
  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
 
89
    if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
 
90
      qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
 
91
      if (*qtblptr == NULL)
 
92
        *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
 
93
      MEMCOPY((*qtblptr)->quantval,
 
94
              srcinfo->quant_tbl_ptrs[tblno]->quantval,
 
95
              SIZEOF((*qtblptr)->quantval));
 
96
      (*qtblptr)->sent_table = FALSE;
 
97
    }
 
98
  }
 
99
  /* Copy the source's per-component info.
 
100
   * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
 
101
   */
 
102
  dstinfo->num_components = srcinfo->num_components;
 
103
  if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
 
104
    ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
 
105
             MAX_COMPONENTS);
 
106
  for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
 
107
       ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
 
108
    outcomp->component_id = incomp->component_id;
 
109
    outcomp->h_samp_factor = incomp->h_samp_factor;
 
110
    outcomp->v_samp_factor = incomp->v_samp_factor;
 
111
    outcomp->quant_tbl_no = incomp->quant_tbl_no;
 
112
    /* Make sure saved quantization table for component matches the qtable
 
113
     * slot.  If not, the input file re-used this qtable slot.
 
114
     * IJG encoder currently cannot duplicate this.
 
115
     */
 
116
    tblno = outcomp->quant_tbl_no;
 
117
    if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
 
118
        srcinfo->quant_tbl_ptrs[tblno] == NULL)
 
119
      ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
 
120
    slot_quant = srcinfo->quant_tbl_ptrs[tblno];
 
121
    c_quant = incomp->quant_table;
 
122
    if (c_quant != NULL) {
 
123
      for (coefi = 0; coefi < DCTSIZE2; coefi++) {
 
124
        if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
 
125
          ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
 
126
      }
 
127
    }
 
128
    /* Note: we do not copy the source's Huffman table assignments;
 
129
     * instead we rely on jpeg_set_colorspace to have made a suitable choice.
 
130
     */
 
131
  }
 
132
  /* Also copy JFIF version and resolution information, if available.
 
133
   * Strictly speaking this isn't "critical" info, but it's nearly
 
134
   * always appropriate to copy it if available.  In particular,
 
135
   * if the application chooses to copy JFIF 1.02 extension markers from
 
136
   * the source file, we need to copy the version to make sure we don't
 
137
   * emit a file that has 1.02 extensions but a claimed version of 1.01.
 
138
   * We will *not*, however, copy version info from mislabeled "2.01" files.
 
139
   */
 
140
  if (srcinfo->saw_JFIF_marker) {
 
141
    if (srcinfo->JFIF_major_version == 1) {
 
142
      dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
 
143
      dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
 
144
    }
 
145
    dstinfo->density_unit = srcinfo->density_unit;
 
146
    dstinfo->X_density = srcinfo->X_density;
 
147
    dstinfo->Y_density = srcinfo->Y_density;
 
148
  }
 
149
}
 
150
 
 
151
 
 
152
/*
 
153
 * Master selection of compression modules for transcoding.
 
154
 * This substitutes for jcinit.c's initialization of the full compressor.
 
155
 */
 
156
 
 
157
LOCAL(void)
 
158
transencode_master_selection (j_compress_ptr cinfo,
 
159
                              jvirt_barray_ptr * coef_arrays)
 
160
{
 
161
  /* Although we don't actually use input_components for transcoding,
 
162
   * jcmaster.c's initial_setup will complain if input_components is 0.
 
163
   */
 
164
  cinfo->input_components = 1;
 
165
  /* Initialize master control (includes parameter checking/processing) */
 
166
  jinit_c_master_control(cinfo, TRUE /* transcode only */);
 
167
 
 
168
  /* Entropy encoding: either Huffman or arithmetic coding. */
 
169
  if (cinfo->arith_code) {
 
170
    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
 
171
  } else {
 
172
    if (cinfo->progressive_mode) {
 
173
#ifdef C_PROGRESSIVE_SUPPORTED
 
174
      jinit_phuff_encoder(cinfo);
 
175
#else
 
176
      ERREXIT(cinfo, JERR_NOT_COMPILED);
 
177
#endif
 
178
    } else
 
179
      jinit_huff_encoder(cinfo);
 
180
  }
 
181
 
 
182
  /* We need a special coefficient buffer controller. */
 
183
  transencode_coef_controller(cinfo, coef_arrays);
 
184
 
 
185
  jinit_marker_writer(cinfo);
 
186
 
 
187
  /* We can now tell the memory manager to allocate virtual arrays. */
 
188
  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
 
189
 
 
190
  /* Write the datastream header (SOI, JFIF) immediately.
 
191
   * Frame and scan headers are postponed till later.
 
192
   * This lets application insert special markers after the SOI.
 
193
   */
 
194
  (*cinfo->marker->write_file_header) (cinfo);
 
195
}
 
196
 
 
197
 
 
198
/*
 
199
 * The rest of this file is a special implementation of the coefficient
 
200
 * buffer controller.  This is similar to jccoefct.c, but it handles only
 
201
 * output from presupplied virtual arrays.  Furthermore, we generate any
 
202
 * dummy padding blocks on-the-fly rather than expecting them to be present
 
203
 * in the arrays.
 
204
 */
 
205
 
 
206
/* Private buffer controller object */
 
207
 
 
208
typedef struct {
 
209
  struct jpeg_c_coef_controller pub; /* public fields */
 
210
 
 
211
  JDIMENSION iMCU_row_num;      /* iMCU row # within image */
 
212
  JDIMENSION mcu_ctr;           /* counts MCUs processed in current row */
 
213
  int MCU_vert_offset;          /* counts MCU rows within iMCU row */
 
214
  int MCU_rows_per_iMCU_row;    /* number of such rows needed */
 
215
 
 
216
  /* Virtual block array for each component. */
 
217
  jvirt_barray_ptr * whole_image;
 
218
 
 
219
  /* Workspace for constructing dummy blocks at right/bottom edges. */
 
220
  JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
 
221
} my_coef_controller;
 
222
 
 
223
typedef my_coef_controller * my_coef_ptr;
 
224
 
 
225
 
 
226
LOCAL(void)
 
227
start_iMCU_row (j_compress_ptr cinfo)
 
228
/* Reset within-iMCU-row counters for a new row */
 
229
{
 
230
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 
231
 
 
232
  /* In an interleaved scan, an MCU row is the same as an iMCU row.
 
233
   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
 
234
   * But at the bottom of the image, process only what's left.
 
235
   */
 
236
  if (cinfo->comps_in_scan > 1) {
 
237
    coef->MCU_rows_per_iMCU_row = 1;
 
238
  } else {
 
239
    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
 
240
      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
 
241
    else
 
242
      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
 
243
  }
 
244
 
 
245
  coef->mcu_ctr = 0;
 
246
  coef->MCU_vert_offset = 0;
 
247
}
 
248
 
 
249
 
 
250
/*
 
251
 * Initialize for a processing pass.
 
252
 */
 
253
 
 
254
METHODDEF(void)
 
255
start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
 
256
{
 
257
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 
258
 
 
259
  if (pass_mode != JBUF_CRANK_DEST)
 
260
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 
261
 
 
262
  coef->iMCU_row_num = 0;
 
263
  start_iMCU_row(cinfo);
 
264
}
 
265
 
 
266
 
 
267
/*
 
268
 * Process some data.
 
269
 * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
 
270
 * per call, ie, v_samp_factor block rows for each component in the scan.
 
271
 * The data is obtained from the virtual arrays and fed to the entropy coder.
 
272
 * Returns TRUE if the iMCU row is completed, FALSE if suspended.
 
273
 *
 
274
 * NB: input_buf is ignored; it is likely to be a NULL pointer.
 
275
 */
 
276
 
 
277
METHODDEF(boolean)
 
278
compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
 
279
{
 
280
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 
281
  JDIMENSION MCU_col_num;       /* index of current MCU within row */
 
282
  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
 
283
  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 
284
  int blkn, ci, xindex, yindex, yoffset, blockcnt;
 
285
  JDIMENSION start_col;
 
286
  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
 
287
  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
 
288
  JBLOCKROW buffer_ptr;
 
289
  jpeg_component_info *compptr;
 
290
 
 
291
  /* Align the virtual buffers for the components used in this scan. */
 
292
  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 
293
    compptr = cinfo->cur_comp_info[ci];
 
294
    buffer[ci] = (*cinfo->mem->access_virt_barray)
 
295
      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
 
296
       coef->iMCU_row_num * compptr->v_samp_factor,
 
297
       (JDIMENSION) compptr->v_samp_factor, FALSE);
 
298
  }
 
299
 
 
300
  /* Loop to process one whole iMCU row */
 
301
  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
 
302
       yoffset++) {
 
303
    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
 
304
         MCU_col_num++) {
 
305
      /* Construct list of pointers to DCT blocks belonging to this MCU */
 
306
      blkn = 0;                 /* index of current DCT block within MCU */
 
307
      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 
308
        compptr = cinfo->cur_comp_info[ci];
 
309
        start_col = MCU_col_num * compptr->MCU_width;
 
310
        blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
 
311
                                                : compptr->last_col_width;
 
312
        for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
 
313
          if (coef->iMCU_row_num < last_iMCU_row ||
 
314
              yindex+yoffset < compptr->last_row_height) {
 
315
            /* Fill in pointers to real blocks in this row */
 
316
            buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
 
317
            for (xindex = 0; xindex < blockcnt; xindex++)
 
318
              MCU_buffer[blkn++] = buffer_ptr++;
 
319
          } else {
 
320
            /* At bottom of image, need a whole row of dummy blocks */
 
321
            xindex = 0;
 
322
          }
 
323
          /* Fill in any dummy blocks needed in this row.
 
324
           * Dummy blocks are filled in the same way as in jccoefct.c:
 
325
           * all zeroes in the AC entries, DC entries equal to previous
 
326
           * block's DC value.  The init routine has already zeroed the
 
327
           * AC entries, so we need only set the DC entries correctly.
 
328
           */
 
329
          for (; xindex < compptr->MCU_width; xindex++) {
 
330
            MCU_buffer[blkn] = coef->dummy_buffer[blkn];
 
331
            MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
 
332
            blkn++;
 
333
          }
 
334
        }
 
335
      }
 
336
      /* Try to write the MCU. */
 
337
      if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
 
338
        /* Suspension forced; update state counters and exit */
 
339
        coef->MCU_vert_offset = yoffset;
 
340
        coef->mcu_ctr = MCU_col_num;
 
341
        return FALSE;
 
342
      }
 
343
    }
 
344
    /* Completed an MCU row, but perhaps not an iMCU row */
 
345
    coef->mcu_ctr = 0;
 
346
  }
 
347
  /* Completed the iMCU row, advance counters for next one */
 
348
  coef->iMCU_row_num++;
 
349
  start_iMCU_row(cinfo);
 
350
  return TRUE;
 
351
}
 
352
 
 
353
 
 
354
/*
 
355
 * Initialize coefficient buffer controller.
 
356
 *
 
357
 * Each passed coefficient array must be the right size for that
 
358
 * coefficient: width_in_blocks wide and height_in_blocks high,
 
359
 * with unitheight at least v_samp_factor.
 
360
 */
 
361
 
 
362
LOCAL(void)
 
363
transencode_coef_controller (j_compress_ptr cinfo,
 
364
                             jvirt_barray_ptr * coef_arrays)
 
365
{
 
366
  my_coef_ptr coef;
 
367
  JBLOCKROW buffer;
 
368
  int i;
 
369
 
 
370
  coef = (my_coef_ptr)
 
371
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 
372
                                SIZEOF(my_coef_controller));
 
373
  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
 
374
  coef->pub.start_pass = start_pass_coef;
 
375
  coef->pub.compress_data = compress_output;
 
376
 
 
377
  /* Save pointer to virtual arrays */
 
378
  coef->whole_image = coef_arrays;
 
379
 
 
380
  /* Allocate and pre-zero space for dummy DCT blocks. */
 
381
  buffer = (JBLOCKROW)
 
382
    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 
383
                                C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
 
384
  jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
 
385
  for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
 
386
    coef->dummy_buffer[i] = buffer + i;
 
387
  }
 
388
}