~ubuntu-branches/debian/lenny/fpc/lenny

« back to all changes in this revision

Viewing changes to fpcsrc/packages/base/pasjpeg/jdmainct.pas

  • Committer: Bazaar Package Importer
  • Author(s): Mazen Neifer, Torsten Werner, Mazen Neifer
  • Date: 2008-05-17 17:12:11 UTC
  • mfrom: (3.1.9 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080517171211-9qi33xhd9evfa0kg
Tags: 2.2.0-dfsg1-9
[ Torsten Werner ]
* Add Mazen Neifer to Uploaders field.

[ Mazen Neifer ]
* Moved FPC sources into a version dependent directory from /usr/share/fpcsrc
  to /usr/share/fpcsrc/${FPCVERSION}. This allow installing more than on FPC
  release.
* Fixed far call issue in compiler preventing building huge binearies.
  (closes: #477743)
* Updated building dependencies, recomennded and suggested packages.
* Moved fppkg to fp-utils as it is just a helper tool and is not required by
  compiler.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Unit JdMainCt;
 
2
 
 
3
 
 
4
{ This file is part of the Independent JPEG Group's software.
 
5
  For conditions of distribution and use, see the accompanying README file.
 
6
 
 
7
  This file contains the main buffer controller for decompression.
 
8
  The main buffer lies between the JPEG decompressor proper and the
 
9
  post-processor; it holds downsampled data in the JPEG colorspace.
 
10
 
 
11
  Note that this code is bypassed in raw-data mode, since the application
 
12
  supplies the equivalent of the main buffer in that case. }
 
13
 
 
14
{ Original: jdmainct.c ; Copyright (C) 1994-1996, Thomas G. Lane.  }
 
15
 
 
16
 
 
17
{ In the current system design, the main buffer need never be a full-image
 
18
  buffer; any full-height buffers will be found inside the coefficient or
 
19
  postprocessing controllers.  Nonetheless, the main controller is not
 
20
  trivial.  Its responsibility is to provide context rows for upsampling/
 
21
  rescaling, and doing this in an efficient fashion is a bit tricky.
 
22
 
 
23
  Postprocessor input data is counted in "row groups".  A row group
 
24
  is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
 
25
  sample rows of each component.  (We require DCT_scaled_size values to be
 
26
  chosen such that these numbers are integers.  In practice DCT_scaled_size
 
27
  values will likely be powers of two, so we actually have the stronger
 
28
  condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
 
29
  Upsampling will typically produce max_v_samp_factor pixel rows from each
 
30
  row group (times any additional scale factor that the upsampler is
 
31
  applying).
 
32
 
 
33
  The coefficient controller will deliver data to us one iMCU row at a time;
 
34
  each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
 
35
  exactly min_DCT_scaled_size row groups.  (This amount of data corresponds
 
36
  to one row of MCUs when the image is fully interleaved.)  Note that the
 
37
  number of sample rows varies across components, but the number of row
 
38
  groups does not.  Some garbage sample rows may be included in the last iMCU
 
39
  row at the bottom of the image.
 
40
 
 
41
  Depending on the vertical scaling algorithm used, the upsampler may need
 
42
  access to the sample row(s) above and below its current input row group.
 
43
  The upsampler is required to set need_context_rows TRUE at global
 
44
  selection
 
45
  time if so.  When need_context_rows is FALSE, this controller can simply
 
46
  obtain one iMCU row at a time from the coefficient controller and dole it
 
47
  out as row groups to the postprocessor.
 
48
 
 
49
  When need_context_rows is TRUE, this controller guarantees that the buffer
 
50
  passed to postprocessing contains at least one row group's worth of samples
 
51
  above and below the row group(s) being processed.  Note that the context
 
52
  rows "above" the first passed row group appear at negative row offsets in
 
53
  the passed buffer.  At the top and bottom of the image, the required
 
54
  context rows are manufactured by duplicating the first or last real sample
 
55
  row; this avoids having special cases in the upsampling inner loops.
 
56
 
 
57
  The amount of context is fixed at one row group just because that's a
 
58
  convenient number for this controller to work with.  The existing
 
59
  upsamplers really only need one sample row of context.  An upsampler
 
60
  supporting arbitrary output rescaling might wish for more than one row
 
61
  group of context when shrinking the image; tough, we don't handle that.
 
62
  (This is justified by the assumption that downsizing will be handled mostly
 
63
  by adjusting the DCT_scaled_size values, so that the actual scale factor at
 
64
  the upsample step needn't be much less than one.)
 
65
 
 
66
  To provide the desired context, we have to retain the last two row groups
 
67
  of one iMCU row while reading in the next iMCU row.  (The last row group
 
68
  can't be processed until we have another row group for its below-context,
 
69
  and so we have to save the next-to-last group too for its above-context.)
 
70
  We could do this most simply by copying data around in our buffer, but
 
71
  that'd be very slow.  We can avoid copying any data by creating a rather
 
72
  strange pointer structure.  Here's how it works.  We allocate a workspace
 
73
  consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
 
74
  of row groups per iMCU row).  We create two sets of redundant pointers to
 
75
  the workspace.  Labeling the physical row groups 0 to M+1, the synthesized
 
76
  pointer lists look like this:
 
77
                    M+1                          M-1
 
78
  master pointer --> 0         master pointer --> 0
 
79
                     1                            1
 
80
                    ...                          ...
 
81
                    M-3                          M-3
 
82
                    M-2                           M
 
83
                    M-1                          M+1
 
84
                     M                           M-2
 
85
                    M+1                          M-1
 
86
                     0                            0
 
87
  We read alternate iMCU rows using each master pointer; thus the last two
 
88
  row groups of the previous iMCU row remain un-overwritten in the workspace.
 
89
  The pointer lists are set up so that the required context rows appear to
 
90
  be adjacent to the proper places when we pass the pointer lists to the
 
91
  upsampler.
 
92
 
 
93
  The above pictures describe the normal state of the pointer lists.
 
94
  At top and bottom of the image, we diddle the pointer lists to duplicate
 
95
  the first or last sample row as necessary (this is cheaper than copying
 
96
  sample rows around).
 
97
 
 
98
  This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1.  In that
 
99
  situation each iMCU row provides only one row group so the buffering logic
 
100
  must be different (eg, we must read two iMCU rows before we can emit the
 
101
  first row group).  For now, we simply do not support providing context
 
102
  rows when min_DCT_scaled_size is 1.  That combination seems unlikely to
 
103
  be worth providing --- if someone wants a 1/8th-size preview, they probably
 
104
  want it quick and dirty, so a context-free upsampler is sufficient. }
 
105
 
 
106
interface
 
107
 
 
108
{$I jconfig.inc}
 
109
 
 
110
uses
 
111
  jmorecfg,
 
112
  jinclude,
 
113
{$ifdef QUANT_2PASS_SUPPORTED}
 
114
  jquant2,
 
115
{$endif}
 
116
  jdeferr,
 
117
  jerror,
 
118
  jpeglib;
 
119
 
 
120
 
 
121
{GLOBAL}
 
122
procedure jinit_d_main_controller (cinfo : j_decompress_ptr;
 
123
                                   need_full_buffer : boolean);
 
124
 
 
125
 
 
126
implementation
 
127
 
 
128
{ Private buffer controller object }
 
129
 
 
130
type
 
131
  my_main_ptr = ^my_main_controller;
 
132
  my_main_controller = record
 
133
    pub : jpeg_d_main_controller; { public fields }
 
134
 
 
135
    { Pointer to allocated workspace (M or M+2 row groups). }
 
136
    buffer : array[0..MAX_COMPONENTS-1] of JSAMPARRAY;
 
137
 
 
138
    buffer_full : boolean;      { Have we gotten an iMCU row from decoder? }
 
139
    rowgroup_ctr : JDIMENSION ; { counts row groups output to postprocessor }
 
140
 
 
141
    { Remaining fields are only used in the context case. }
 
142
 
 
143
    { These are the master pointers to the funny-order pointer lists. }
 
144
    xbuffer : array[0..2-1] of JSAMPIMAGE;      { pointers to weird pointer lists }
 
145
 
 
146
    whichptr : int;                     { indicates which pointer set is now in use }
 
147
    context_state : int;                { process_data state machine status }
 
148
    rowgroups_avail : JDIMENSION;       { row groups available to postprocessor }
 
149
    iMCU_row_ctr : JDIMENSION;  { counts iMCU rows to detect image top/bot }
 
150
  end; { my_main_controller; }
 
151
 
 
152
 
 
153
{ context_state values: }
 
154
const
 
155
  CTX_PREPARE_FOR_IMCU  = 0;    { need to prepare for MCU row }
 
156
  CTX_PROCESS_IMCU      = 1;    { feeding iMCU to postprocessor }
 
157
  CTX_POSTPONED_ROW     = 2;    { feeding postponed row group }
 
158
 
 
159
 
 
160
{ Forward declarations }
 
161
{METHODDEF}
 
162
procedure process_data_simple_main(cinfo : j_decompress_ptr;
 
163
                                   output_buf : JSAMPARRAY;
 
164
                                   var out_row_ctr : JDIMENSION;
 
165
                                   out_rows_avail : JDIMENSION); far; forward;
 
166
{METHODDEF}
 
167
procedure process_data_context_main (cinfo : j_decompress_ptr;
 
168
                                     output_buf : JSAMPARRAY;
 
169
                                     var out_row_ctr : JDIMENSION;
 
170
                                     out_rows_avail : JDIMENSION); far; forward;
 
171
 
 
172
{$ifdef QUANT_2PASS_SUPPORTED}
 
173
{METHODDEF}
 
174
procedure process_data_crank_post (cinfo : j_decompress_ptr;
 
175
                                     output_buf : JSAMPARRAY;
 
176
                                     var out_row_ctr : JDIMENSION;
 
177
                                     out_rows_avail : JDIMENSION); far; forward;
 
178
{$endif}
 
179
 
 
180
 
 
181
{LOCAL}
 
182
procedure alloc_funny_pointers (cinfo : j_decompress_ptr);
 
183
{ Allocate space for the funny pointer lists.
 
184
  This is done only once, not once per pass. }
 
185
var
 
186
  main : my_main_ptr;
 
187
  ci, rgroup : int;
 
188
  M : int;
 
189
  compptr : jpeg_component_info_ptr;
 
190
  xbuf : JSAMPARRAY;
 
191
begin
 
192
  main := my_main_ptr (cinfo^.main);
 
193
  M := cinfo^.min_DCT_scaled_size;
 
194
 
 
195
  { Get top-level space for component array pointers.
 
196
    We alloc both arrays with one call to save a few cycles. }
 
197
 
 
198
  main^.xbuffer[0] := JSAMPIMAGE (
 
199
    cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
 
200
                      cinfo^.num_components * 2 * SIZEOF(JSAMPARRAY)) );
 
201
  main^.xbuffer[1] := JSAMPIMAGE(@( main^.xbuffer[0]^[cinfo^.num_components] ));
 
202
 
 
203
  compptr := jpeg_component_info_ptr(cinfo^.comp_info);
 
204
  for ci := 0 to pred(cinfo^.num_components) do
 
205
  begin
 
206
    rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
 
207
      cinfo^.min_DCT_scaled_size; { height of a row group of component }
 
208
    { Get space for pointer lists --- M+4 row groups in each list.
 
209
      We alloc both pointer lists with one call to save a few cycles. }
 
210
 
 
211
    xbuf := JSAMPARRAY (
 
212
      cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
 
213
                                 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)) );
 
214
    Inc(JSAMPROW_PTR(xbuf), rgroup); { want one row group at negative offsets }
 
215
    main^.xbuffer[0]^[ci] := xbuf;
 
216
    Inc(JSAMPROW_PTR(xbuf), rgroup * (M + 4));
 
217
    main^.xbuffer[1]^[ci] := xbuf;
 
218
    Inc(compptr);
 
219
  end;
 
220
end;
 
221
 
 
222
{LOCAL}
 
223
procedure make_funny_pointers (cinfo : j_decompress_ptr);
 
224
{ Create the funny pointer lists discussed in the comments above.
 
225
  The actual workspace is already allocated (in main^.buffer),
 
226
  and the space for the pointer lists is allocated too.
 
227
  This routine just fills in the curiously ordered lists.
 
228
  This will be repeated at the beginning of each pass. }
 
229
var
 
230
  main : my_main_ptr;
 
231
  ci, i, rgroup : int;
 
232
  M : int;
 
233
  compptr : jpeg_component_info_ptr;
 
234
  buf, xbuf0, xbuf1 : JSAMPARRAY;
 
235
var
 
236
  help_xbuf0 : JSAMPARRAY;       { work around negative offsets }
 
237
begin
 
238
  main := my_main_ptr (cinfo^.main);
 
239
  M := cinfo^.min_DCT_scaled_size;
 
240
 
 
241
  compptr := jpeg_component_info_ptr(cinfo^.comp_info);
 
242
  for ci := 0 to pred(cinfo^.num_components) do
 
243
  begin
 
244
    rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
 
245
      cinfo^.min_DCT_scaled_size; { height of a row group of component }
 
246
    xbuf0 := main^.xbuffer[0]^[ci];
 
247
    xbuf1 := main^.xbuffer[1]^[ci];
 
248
    { First copy the workspace pointers as-is }
 
249
    buf := main^.buffer[ci];
 
250
    for i := 0 to pred(rgroup * (M + 2)) do
 
251
    begin
 
252
      xbuf0^[i] := buf^[i];
 
253
      xbuf1^[i] := buf^[i];
 
254
    end;
 
255
    { In the second list, put the last four row groups in swapped order }
 
256
    for i := 0 to pred(rgroup * 2) do
 
257
    begin
 
258
      xbuf1^[rgroup*(M-2) + i] := buf^[rgroup*M + i];
 
259
      xbuf1^[rgroup*M + i] := buf^[rgroup*(M-2) + i];
 
260
    end;
 
261
    { The wraparound pointers at top and bottom will be filled later
 
262
      (see set_wraparound_pointers, below).  Initially we want the "above"
 
263
      pointers to duplicate the first actual data line.  This only needs
 
264
      to happen in xbuffer[0]. }
 
265
 
 
266
    help_xbuf0 := xbuf0;
 
267
    Dec(JSAMPROW_PTR(help_xbuf0), rgroup);
 
268
 
 
269
    for i := 0 to pred(rgroup) do
 
270
    begin
 
271
      {xbuf0^[i - rgroup] := xbuf0^[0];}
 
272
      help_xbuf0^[i] := xbuf0^[0];
 
273
    end;
 
274
    Inc(compptr);
 
275
  end;
 
276
end;
 
277
 
 
278
 
 
279
{LOCAL}
 
280
procedure set_wraparound_pointers (cinfo : j_decompress_ptr);
 
281
{ Set up the "wraparound" pointers at top and bottom of the pointer lists.
 
282
  This changes the pointer list state from top-of-image to the normal state. }
 
283
var
 
284
  main : my_main_ptr;
 
285
  ci, i, rgroup : int;
 
286
  M : int;
 
287
  compptr : jpeg_component_info_ptr;
 
288
  xbuf0, xbuf1 : JSAMPARRAY;
 
289
var
 
290
  help_xbuf0,
 
291
  help_xbuf1 : JSAMPARRAY;       { work around negative offsets }
 
292
begin
 
293
  main := my_main_ptr (cinfo^.main);
 
294
  M := cinfo^.min_DCT_scaled_size;
 
295
 
 
296
  compptr := jpeg_component_info_ptr(cinfo^.comp_info);
 
297
  for ci := 0 to pred(cinfo^.num_components) do
 
298
  begin
 
299
    rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
 
300
      cinfo^.min_DCT_scaled_size; { height of a row group of component }
 
301
    xbuf0 := main^.xbuffer[0]^[ci];
 
302
    xbuf1 := main^.xbuffer[1]^[ci];
 
303
 
 
304
    help_xbuf0 := xbuf0;
 
305
    Dec(JSAMPROW_PTR(help_xbuf0), rgroup);
 
306
    help_xbuf1 := xbuf1;
 
307
    Dec(JSAMPROW_PTR(help_xbuf1), rgroup);
 
308
 
 
309
    for i := 0 to pred(rgroup) do
 
310
    begin
 
311
      {xbuf0^[i - rgroup] := xbuf0^[rgroup*(M+1) + i];
 
312
      xbuf1^[i - rgroup] := xbuf1^[rgroup*(M+1) + i];}
 
313
 
 
314
      help_xbuf0^[i] := xbuf0^[rgroup*(M+1) + i];
 
315
      help_xbuf1^[i] := xbuf1^[rgroup*(M+1) + i];
 
316
 
 
317
      xbuf0^[rgroup*(M+2) + i] := xbuf0^[i];
 
318
      xbuf1^[rgroup*(M+2) + i] := xbuf1^[i];
 
319
    end;
 
320
    Inc(compptr);
 
321
  end;
 
322
end;
 
323
 
 
324
 
 
325
{LOCAL}
 
326
procedure set_bottom_pointers (cinfo : j_decompress_ptr);
 
327
{ Change the pointer lists to duplicate the last sample row at the bottom
 
328
  of the image.  whichptr indicates which xbuffer holds the final iMCU row.
 
329
  Also sets rowgroups_avail to indicate number of nondummy row groups in row. }
 
330
var
 
331
  main : my_main_ptr;
 
332
  ci, i, rgroup, iMCUheight, rows_left : int;
 
333
  compptr : jpeg_component_info_ptr;
 
334
  xbuf : JSAMPARRAY;
 
335
begin
 
336
  main := my_main_ptr (cinfo^.main);
 
337
 
 
338
  compptr := jpeg_component_info_ptr(cinfo^.comp_info);
 
339
  for ci := 0 to pred(cinfo^.num_components) do
 
340
  begin
 
341
    { Count sample rows in one iMCU row and in one row group }
 
342
    iMCUheight := compptr^.v_samp_factor * compptr^.DCT_scaled_size;
 
343
    rgroup := iMCUheight div cinfo^.min_DCT_scaled_size;
 
344
    { Count nondummy sample rows remaining for this component }
 
345
    rows_left := int (compptr^.downsampled_height mod JDIMENSION (iMCUheight));
 
346
    if (rows_left = 0) then
 
347
      rows_left := iMCUheight;
 
348
    { Count nondummy row groups.  Should get same answer for each component,
 
349
      so we need only do it once. }
 
350
    if (ci = 0) then
 
351
    begin
 
352
      main^.rowgroups_avail := JDIMENSION ((rows_left-1) div rgroup + 1);
 
353
    end;
 
354
    { Duplicate the last real sample row rgroup*2 times; this pads out the
 
355
      last partial rowgroup and ensures at least one full rowgroup of context. }
 
356
 
 
357
    xbuf := main^.xbuffer[main^.whichptr]^[ci];
 
358
    for i := 0 to pred(rgroup * 2) do
 
359
    begin
 
360
      xbuf^[rows_left + i] := xbuf^[rows_left-1];
 
361
    end;
 
362
    Inc(compptr);
 
363
  end;
 
364
end;
 
365
 
 
366
 
 
367
{ Initialize for a processing pass. }
 
368
 
 
369
{METHODDEF}
 
370
procedure start_pass_main (cinfo : j_decompress_ptr;
 
371
                           pass_mode : J_BUF_MODE); far;
 
372
var
 
373
  main : my_main_ptr;
 
374
begin
 
375
  main := my_main_ptr (cinfo^.main);
 
376
 
 
377
  case (pass_mode) of
 
378
  JBUF_PASS_THRU:
 
379
    begin
 
380
      if (cinfo^.upsample^.need_context_rows) then
 
381
      begin
 
382
        main^.pub.process_data := process_data_context_main;
 
383
        make_funny_pointers(cinfo); { Create the xbuffer[] lists }
 
384
        main^.whichptr := 0;    { Read first iMCU row into xbuffer[0] }
 
385
        main^.context_state := CTX_PREPARE_FOR_IMCU;
 
386
        main^.iMCU_row_ctr := 0;
 
387
      end
 
388
      else
 
389
      begin
 
390
        { Simple case with no context needed }
 
391
        main^.pub.process_data := process_data_simple_main;
 
392
      end;
 
393
      main^.buffer_full := FALSE;       { Mark buffer empty }
 
394
      main^.rowgroup_ctr := 0;
 
395
    end;
 
396
{$ifdef QUANT_2PASS_SUPPORTED}
 
397
  JBUF_CRANK_DEST:
 
398
    { For last pass of 2-pass quantization, just crank the postprocessor }
 
399
    main^.pub.process_data := process_data_crank_post;
 
400
{$endif}
 
401
  else
 
402
    ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
 
403
  end;
 
404
end;
 
405
 
 
406
 
 
407
{ Process some data.
 
408
  This handles the simple case where no context is required. }
 
409
 
 
410
{METHODDEF}
 
411
procedure process_data_simple_main (cinfo : j_decompress_ptr;
 
412
                                    output_buf : JSAMPARRAY;
 
413
                                    var out_row_ctr : JDIMENSION;
 
414
                                    out_rows_avail : JDIMENSION);
 
415
var
 
416
  main : my_main_ptr;
 
417
  rowgroups_avail : JDIMENSION;
 
418
var
 
419
  main_buffer_ptr : JSAMPIMAGE;
 
420
begin
 
421
  main := my_main_ptr (cinfo^.main);
 
422
  main_buffer_ptr := JSAMPIMAGE(@(main^.buffer));
 
423
 
 
424
  { Read input data if we haven't filled the main buffer yet }
 
425
  if (not main^.buffer_full) then
 
426
  begin
 
427
    if (cinfo^.coef^.decompress_data (cinfo, main_buffer_ptr)=0) then
 
428
      exit;                     { suspension forced, can do nothing more }
 
429
    main^.buffer_full := TRUE;  { OK, we have an iMCU row to work with }
 
430
  end;
 
431
 
 
432
  { There are always min_DCT_scaled_size row groups in an iMCU row. }
 
433
  rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size);
 
434
  { Note: at the bottom of the image, we may pass extra garbage row groups
 
435
    to the postprocessor.  The postprocessor has to check for bottom
 
436
    of image anyway (at row resolution), so no point in us doing it too. }
 
437
 
 
438
  { Feed the postprocessor }
 
439
  cinfo^.post^.post_process_data (cinfo, main_buffer_ptr,
 
440
                                  main^.rowgroup_ctr, rowgroups_avail,
 
441
                                  output_buf, out_row_ctr, out_rows_avail);
 
442
 
 
443
  { Has postprocessor consumed all the data yet? If so, mark buffer empty }
 
444
  if (main^.rowgroup_ctr >= rowgroups_avail) then
 
445
  begin
 
446
    main^.buffer_full := FALSE;
 
447
    main^.rowgroup_ctr := 0;
 
448
  end;
 
449
end;
 
450
 
 
451
 
 
452
{ Process some data.
 
453
  This handles the case where context rows must be provided. }
 
454
 
 
455
{METHODDEF}
 
456
procedure process_data_context_main (cinfo : j_decompress_ptr;
 
457
                                     output_buf : JSAMPARRAY;
 
458
                                     var out_row_ctr : JDIMENSION;
 
459
                                     out_rows_avail : JDIMENSION);
 
460
var
 
461
  main : my_main_ptr;
 
462
begin
 
463
  main := my_main_ptr (cinfo^.main);
 
464
 
 
465
  { Read input data if we haven't filled the main buffer yet }
 
466
  if (not main^.buffer_full) then
 
467
  begin
 
468
    if (cinfo^.coef^.decompress_data (cinfo,
 
469
                          main^.xbuffer[main^.whichptr])=0) then
 
470
      exit;                     { suspension forced, can do nothing more }
 
471
    main^.buffer_full := TRUE;  { OK, we have an iMCU row to work with }
 
472
    Inc(main^.iMCU_row_ctr);    { count rows received }
 
473
  end;
 
474
 
 
475
  { Postprocessor typically will not swallow all the input data it is handed
 
476
    in one call (due to filling the output buffer first).  Must be prepared
 
477
    to exit and restart.  This switch lets us keep track of how far we got.
 
478
    Note that each case falls through to the next on successful completion. }
 
479
 
 
480
  case (main^.context_state) of
 
481
  CTX_POSTPONED_ROW:
 
482
    begin
 
483
      { Call postprocessor using previously set pointers for postponed row }
 
484
      cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr],
 
485
                          main^.rowgroup_ctr, main^.rowgroups_avail,
 
486
                          output_buf, out_row_ctr, out_rows_avail);
 
487
      if (main^.rowgroup_ctr < main^.rowgroups_avail) then
 
488
        exit;                   { Need to suspend }
 
489
      main^.context_state := CTX_PREPARE_FOR_IMCU;
 
490
      if (out_row_ctr >= out_rows_avail) then
 
491
        exit;                   { Postprocessor exactly filled output buf }
 
492
    end;
 
493
  end;
 
494
  case (main^.context_state) of
 
495
  CTX_POSTPONED_ROW,
 
496
  CTX_PREPARE_FOR_IMCU:  {FALLTHROUGH}
 
497
    begin
 
498
      { Prepare to process first M-1 row groups of this iMCU row }
 
499
      main^.rowgroup_ctr := 0;
 
500
      main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size - 1);
 
501
      { Check for bottom of image: if so, tweak pointers to "duplicate"
 
502
        the last sample row, and adjust rowgroups_avail to ignore padding rows. }
 
503
 
 
504
      if (main^.iMCU_row_ctr = cinfo^.total_iMCU_rows) then
 
505
        set_bottom_pointers(cinfo);
 
506
      main^.context_state := CTX_PROCESS_IMCU;
 
507
 
 
508
    end;
 
509
  end;
 
510
  case (main^.context_state) of
 
511
  CTX_POSTPONED_ROW,
 
512
  CTX_PREPARE_FOR_IMCU,  {FALLTHROUGH}
 
513
  CTX_PROCESS_IMCU:
 
514
    begin
 
515
      { Call postprocessor using previously set pointers }
 
516
      cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr],
 
517
                          main^.rowgroup_ctr, main^.rowgroups_avail,
 
518
                          output_buf, out_row_ctr, out_rows_avail);
 
519
      if (main^.rowgroup_ctr < main^.rowgroups_avail) then
 
520
        exit;                   { Need to suspend }
 
521
      { After the first iMCU, change wraparound pointers to normal state }
 
522
      if (main^.iMCU_row_ctr = 1) then
 
523
        set_wraparound_pointers(cinfo);
 
524
      { Prepare to load new iMCU row using other xbuffer list }
 
525
      main^.whichptr := main^.whichptr xor 1;   { 0=>1 or 1=>0 }
 
526
      main^.buffer_full := FALSE;
 
527
      { Still need to process last row group of this iMCU row, }
 
528
      { which is saved at index M+1 of the other xbuffer }
 
529
      main^.rowgroup_ctr := JDIMENSION (cinfo^.min_DCT_scaled_size + 1);
 
530
      main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size + 2);
 
531
      main^.context_state := CTX_POSTPONED_ROW;
 
532
    end;
 
533
  end;
 
534
end;
 
535
 
 
536
 
 
537
{ Process some data.
 
538
  Final pass of two-pass quantization: just call the postprocessor.
 
539
  Source data will be the postprocessor controller's internal buffer. }
 
540
 
 
541
{$ifdef QUANT_2PASS_SUPPORTED}
 
542
 
 
543
{METHODDEF}
 
544
procedure process_data_crank_post (cinfo : j_decompress_ptr;
 
545
                                   output_buf : JSAMPARRAY;
 
546
                                   var out_row_ctr : JDIMENSION;
 
547
                                   out_rows_avail : JDIMENSION);
 
548
var
 
549
  in_row_group_ctr : JDIMENSION;
 
550
begin
 
551
  in_row_group_ctr := 0;
 
552
  cinfo^.post^.post_process_data (cinfo, JSAMPIMAGE (NIL),
 
553
                                     in_row_group_ctr,
 
554
                                     JDIMENSION(0),
 
555
                                     output_buf,
 
556
                                     out_row_ctr,
 
557
                                     out_rows_avail);
 
558
end;
 
559
 
 
560
{$endif} { QUANT_2PASS_SUPPORTED }
 
561
 
 
562
 
 
563
{ Initialize main buffer controller. }
 
564
 
 
565
{GLOBAL}
 
566
procedure jinit_d_main_controller (cinfo : j_decompress_ptr;
 
567
                                   need_full_buffer : boolean);
 
568
var
 
569
  main : my_main_ptr;
 
570
  ci, rgroup, ngroups : int;
 
571
  compptr : jpeg_component_info_ptr;
 
572
begin
 
573
  main := my_main_ptr(
 
574
    cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
 
575
                                SIZEOF(my_main_controller)) );
 
576
  cinfo^.main := jpeg_d_main_controller_ptr(main);
 
577
  main^.pub.start_pass := start_pass_main;
 
578
 
 
579
  if (need_full_buffer) then    { shouldn't happen }
 
580
    ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
 
581
 
 
582
  { Allocate the workspace.
 
583
    ngroups is the number of row groups we need.}
 
584
 
 
585
  if (cinfo^.upsample^.need_context_rows) then
 
586
  begin
 
587
    if (cinfo^.min_DCT_scaled_size < 2) then { unsupported, see comments above }
 
588
      ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL);
 
589
    alloc_funny_pointers(cinfo); { Alloc space for xbuffer[] lists }
 
590
    ngroups := cinfo^.min_DCT_scaled_size + 2;
 
591
  end
 
592
  else
 
593
  begin
 
594
    ngroups := cinfo^.min_DCT_scaled_size;
 
595
  end;
 
596
 
 
597
  compptr := jpeg_component_info_ptr(cinfo^.comp_info);
 
598
  for ci := 0 to pred(cinfo^.num_components) do
 
599
  begin
 
600
    rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
 
601
      cinfo^.min_DCT_scaled_size; { height of a row group of component }
 
602
    main^.buffer[ci] := cinfo^.mem^.alloc_sarray
 
603
                        (j_common_ptr(cinfo), JPOOL_IMAGE,
 
604
                         compptr^.width_in_blocks * compptr^.DCT_scaled_size,
 
605
                         JDIMENSION (rgroup * ngroups));
 
606
    Inc(compptr);
 
607
  end;
 
608
end;
 
609
 
 
610
end.