source: trunk/src/3rdparty/libjpeg/structure.txt@ 1126

Last change on this file since 1126 was 846, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 50.5 KB
Line 
1IJG JPEG LIBRARY: SYSTEM ARCHITECTURE
2
3Copyright (C) 1991-2009, Thomas G. Lane, Guido Vollbeding.
4This file is part of the Independent JPEG Group's software.
5For conditions of distribution and use, see the accompanying README file.
6
7
8This file provides an overview of the architecture of the IJG JPEG software;
9that is, the functions of the various modules in the system and the interfaces
10between modules. For more precise details about any data structure or calling
11convention, see the include files and comments in the source code.
12
13We assume that the reader is already somewhat familiar with the JPEG standard.
14The README file includes references for learning about JPEG. The file
15libjpeg.txt describes the library from the viewpoint of an application
16programmer using the library; it's best to read that file before this one.
17Also, the file coderules.txt describes the coding style conventions we use.
18
19In this document, JPEG-specific terminology follows the JPEG standard:
20 A "component" means a color channel, e.g., Red or Luminance.
21 A "sample" is a single component value (i.e., one number in the image data).
22 A "coefficient" is a frequency coefficient (a DCT transform output number).
23 A "block" is an 8x8 group of samples or coefficients.
24 An "MCU" (minimum coded unit) is an interleaved set of blocks of size
25 determined by the sampling factors, or a single block in a
26 noninterleaved scan.
27We do not use the terms "pixel" and "sample" interchangeably. When we say
28pixel, we mean an element of the full-size image, while a sample is an element
29of the downsampled image. Thus the number of samples may vary across
30components while the number of pixels does not. (This terminology is not used
31rigorously throughout the code, but it is used in places where confusion would
32otherwise result.)
33
34
35*** System features ***
36
37The IJG distribution contains two parts:
38 * A subroutine library for JPEG compression and decompression.
39 * cjpeg/djpeg, two sample applications that use the library to transform
40 JFIF JPEG files to and from several other image formats.
41cjpeg/djpeg are of no great intellectual complexity: they merely add a simple
42command-line user interface and I/O routines for several uncompressed image
43formats. This document concentrates on the library itself.
44
45We desire the library to be capable of supporting all JPEG baseline, extended
46sequential, and progressive DCT processes. Hierarchical processes are not
47supported.
48
49The library does not support the lossless (spatial) JPEG process. Lossless
50JPEG shares little or no code with lossy JPEG, and would normally be used
51without the extensive pre- and post-processing provided by this library.
52We feel that lossless JPEG is better handled by a separate library.
53
54Within these limits, any set of compression parameters allowed by the JPEG
55spec should be readable for decompression. (We can be more restrictive about
56what formats we can generate.) Although the system design allows for all
57parameter values, some uncommon settings are not yet implemented and may
58never be; nonintegral sampling ratios are the prime example. Furthermore,
59we treat 8-bit vs. 12-bit data precision as a compile-time switch, not a
60run-time option, because most machines can store 8-bit pixels much more
61compactly than 12-bit.
62
63By itself, the library handles only interchange JPEG datastreams --- in
64particular the widely used JFIF file format. The library can be used by
65surrounding code to process interchange or abbreviated JPEG datastreams that
66are embedded in more complex file formats. (For example, libtiff uses this
67library to implement JPEG compression within the TIFF file format.)
68
69The library includes a substantial amount of code that is not covered by the
70JPEG standard but is necessary for typical applications of JPEG. These
71functions preprocess the image before JPEG compression or postprocess it after
72decompression. They include colorspace conversion, downsampling/upsampling,
73and color quantization. This code can be omitted if not needed.
74
75A wide range of quality vs. speed tradeoffs are possible in JPEG processing,
76and even more so in decompression postprocessing. The decompression library
77provides multiple implementations that cover most of the useful tradeoffs,
78ranging from very-high-quality down to fast-preview operation. On the
79compression side we have generally not provided low-quality choices, since
80compression is normally less time-critical. It should be understood that the
81low-quality modes may not meet the JPEG standard's accuracy requirements;
82nonetheless, they are useful for viewers.
83
84
85*** Portability issues ***
86
87Portability is an essential requirement for the library. The key portability
88issues that show up at the level of system architecture are:
89
901. Memory usage. We want the code to be able to run on PC-class machines
91with limited memory. Images should therefore be processed sequentially (in
92strips), to avoid holding the whole image in memory at once. Where a
93full-image buffer is necessary, we should be able to use either virtual memory
94or temporary files.
95
962. Near/far pointer distinction. To run efficiently on 80x86 machines, the
97code should distinguish "small" objects (kept in near data space) from
98"large" ones (kept in far data space). This is an annoying restriction, but
99fortunately it does not impact code quality for less brain-damaged machines,
100and the source code clutter turns out to be minimal with sufficient use of
101pointer typedefs.
102
1033. Data precision. We assume that "char" is at least 8 bits, "short" and
104"int" at least 16, "long" at least 32. The code will work fine with larger
105data sizes, although memory may be used inefficiently in some cases. However,
106the JPEG compressed datastream must ultimately appear on external storage as a
107sequence of 8-bit bytes if it is to conform to the standard. This may pose a
108problem on machines where char is wider than 8 bits. The library represents
109compressed data as an array of values of typedef JOCTET. If no data type
110exactly 8 bits wide is available, custom data source and data destination
111modules must be written to unpack and pack the chosen JOCTET datatype into
1128-bit external representation.
113
114
115*** System overview ***
116
117The compressor and decompressor are each divided into two main sections:
118the JPEG compressor or decompressor proper, and the preprocessing or
119postprocessing functions. The interface between these two sections is the
120image data that the official JPEG spec regards as its input or output: this
121data is in the colorspace to be used for compression, and it is downsampled
122to the sampling factors to be used. The preprocessing and postprocessing
123steps are responsible for converting a normal image representation to or from
124this form. (Those few applications that want to deal with YCbCr downsampled
125data can skip the preprocessing or postprocessing step.)
126
127Looking more closely, the compressor library contains the following main
128elements:
129
130 Preprocessing:
131 * Color space conversion (e.g., RGB to YCbCr).
132 * Edge expansion and downsampling. Optionally, this step can do simple
133 smoothing --- this is often helpful for low-quality source data.
134 JPEG proper:
135 * MCU assembly, DCT, quantization.
136 * Entropy coding (sequential or progressive, Huffman or arithmetic).
137
138In addition to these modules we need overall control, marker generation,
139and support code (memory management & error handling). There is also a
140module responsible for physically writing the output data --- typically
141this is just an interface to fwrite(), but some applications may need to
142do something else with the data.
143
144The decompressor library contains the following main elements:
145
146 JPEG proper:
147 * Entropy decoding (sequential or progressive, Huffman or arithmetic).
148 * Dequantization, inverse DCT, MCU disassembly.
149 Postprocessing:
150 * Upsampling. Optionally, this step may be able to do more general
151 rescaling of the image.
152 * Color space conversion (e.g., YCbCr to RGB). This step may also
153 provide gamma adjustment [ currently it does not ].
154 * Optional color quantization (e.g., reduction to 256 colors).
155 * Optional color precision reduction (e.g., 24-bit to 15-bit color).
156 [This feature is not currently implemented.]
157
158We also need overall control, marker parsing, and a data source module.
159The support code (memory management & error handling) can be shared with
160the compression half of the library.
161
162There may be several implementations of each of these elements, particularly
163in the decompressor, where a wide range of speed/quality tradeoffs is very
164useful. It must be understood that some of the best speedups involve
165merging adjacent steps in the pipeline. For example, upsampling, color space
166conversion, and color quantization might all be done at once when using a
167low-quality ordered-dither technique. The system architecture is designed to
168allow such merging where appropriate.
169
170
171Note: it is convenient to regard edge expansion (padding to block boundaries)
172as a preprocessing/postprocessing function, even though the JPEG spec includes
173it in compression/decompression. We do this because downsampling/upsampling
174can be simplified a little if they work on padded data: it's not necessary to
175have special cases at the right and bottom edges. Therefore the interface
176buffer is always an integral number of blocks wide and high, and we expect
177compression preprocessing to pad the source data properly. Padding will occur
178only to the next block (8-sample) boundary. In an interleaved-scan situation,
179additional dummy blocks may be used to fill out MCUs, but the MCU assembly and
180disassembly logic will create or discard these blocks internally. (This is
181advantageous for speed reasons, since we avoid DCTing the dummy blocks.
182It also permits a small reduction in file size, because the compressor can
183choose dummy block contents so as to minimize their size in compressed form.
184Finally, it makes the interface buffer specification independent of whether
185the file is actually interleaved or not.) Applications that wish to deal
186directly with the downsampled data must provide similar buffering and padding
187for odd-sized images.
188
189
190*** Poor man's object-oriented programming ***
191
192It should be clear by now that we have a lot of quasi-independent processing
193steps, many of which have several possible behaviors. To avoid cluttering the
194code with lots of switch statements, we use a simple form of object-style
195programming to separate out the different possibilities.
196
197For example, two different color quantization algorithms could be implemented
198as two separate modules that present the same external interface; at runtime,
199the calling code will access the proper module indirectly through an "object".
200
201We can get the limited features we need while staying within portable C.
202The basic tool is a function pointer. An "object" is just a struct
203containing one or more function pointer fields, each of which corresponds to
204a method name in real object-oriented languages. During initialization we
205fill in the function pointers with references to whichever module we have
206determined we need to use in this run. Then invocation of the module is done
207by indirecting through a function pointer; on most machines this is no more
208expensive than a switch statement, which would be the only other way of
209making the required run-time choice. The really significant benefit, of
210course, is keeping the source code clean and well structured.
211
212We can also arrange to have private storage that varies between different
213implementations of the same kind of object. We do this by making all the
214module-specific object structs be separately allocated entities, which will
215be accessed via pointers in the master compression or decompression struct.
216The "public" fields or methods for a given kind of object are specified by
217a commonly known struct. But a module's initialization code can allocate
218a larger struct that contains the common struct as its first member, plus
219additional private fields. With appropriate pointer casting, the module's
220internal functions can access these private fields. (For a simple example,
221see jdatadst.c, which implements the external interface specified by struct
222jpeg_destination_mgr, but adds extra fields.)
223
224(Of course this would all be a lot easier if we were using C++, but we are
225not yet prepared to assume that everyone has a C++ compiler.)
226
227An important benefit of this scheme is that it is easy to provide multiple
228versions of any method, each tuned to a particular case. While a lot of
229precalculation might be done to select an optimal implementation of a method,
230the cost per invocation is constant. For example, the upsampling step might
231have a "generic" method, plus one or more "hardwired" methods for the most
232popular sampling factors; the hardwired methods would be faster because they'd
233use straight-line code instead of for-loops. The cost to determine which
234method to use is paid only once, at startup, and the selection criteria are
235hidden from the callers of the method.
236
237This plan differs a little bit from usual object-oriented structures, in that
238only one instance of each object class will exist during execution. The
239reason for having the class structure is that on different runs we may create
240different instances (choose to execute different modules). You can think of
241the term "method" as denoting the common interface presented by a particular
242set of interchangeable functions, and "object" as denoting a group of related
243methods, or the total shared interface behavior of a group of modules.
244
245
246*** Overall control structure ***
247
248We previously mentioned the need for overall control logic in the compression
249and decompression libraries. In IJG implementations prior to v5, overall
250control was mostly provided by "pipeline control" modules, which proved to be
251large, unwieldy, and hard to understand. To improve the situation, the
252control logic has been subdivided into multiple modules. The control modules
253consist of:
254
2551. Master control for module selection and initialization. This has two
256responsibilities:
257
258 1A. Startup initialization at the beginning of image processing.
259 The individual processing modules to be used in this run are selected
260 and given initialization calls.
261
262 1B. Per-pass control. This determines how many passes will be performed
263 and calls each active processing module to configure itself
264 appropriately at the beginning of each pass. End-of-pass processing,
265 where necessary, is also invoked from the master control module.
266
267 Method selection is partially distributed, in that a particular processing
268 module may contain several possible implementations of a particular method,
269 which it will select among when given its initialization call. The master
270 control code need only be concerned with decisions that affect more than
271 one module.
272
2732. Data buffering control. A separate control module exists for each
274 inter-processing-step data buffer. This module is responsible for
275 invoking the processing steps that write or read that data buffer.
276
277Each buffer controller sees the world as follows:
278
279input data => processing step A => buffer => processing step B => output data
280 | | |
281 ------------------ controller ------------------
282
283The controller knows the dataflow requirements of steps A and B: how much data
284they want to accept in one chunk and how much they output in one chunk. Its
285function is to manage its buffer and call A and B at the proper times.
286
287A data buffer control module may itself be viewed as a processing step by a
288higher-level control module; thus the control modules form a binary tree with
289elementary processing steps at the leaves of the tree.
290
291The control modules are objects. A considerable amount of flexibility can
292be had by replacing implementations of a control module. For example:
293* Merging of adjacent steps in the pipeline is done by replacing a control
294 module and its pair of processing-step modules with a single processing-
295 step module. (Hence the possible merges are determined by the tree of
296 control modules.)
297* In some processing modes, a given interstep buffer need only be a "strip"
298 buffer large enough to accommodate the desired data chunk sizes. In other
299 modes, a full-image buffer is needed and several passes are required.
300 The control module determines which kind of buffer is used and manipulates
301 virtual array buffers as needed. One or both processing steps may be
302 unaware of the multi-pass behavior.
303
304In theory, we might be able to make all of the data buffer controllers
305interchangeable and provide just one set of implementations for all. In
306practice, each one contains considerable special-case processing for its
307particular job. The buffer controller concept should be regarded as an
308overall system structuring principle, not as a complete description of the
309task performed by any one controller.
310
311
312*** Compression object structure ***
313
314Here is a sketch of the logical structure of the JPEG compression library:
315
316 |-- Colorspace conversion
317 |-- Preprocessing controller --|
318 | |-- Downsampling
319Main controller --|
320 | |-- Forward DCT, quantize
321 |-- Coefficient controller --|
322 |-- Entropy encoding
323
324This sketch also describes the flow of control (subroutine calls) during
325typical image data processing. Each of the components shown in the diagram is
326an "object" which may have several different implementations available. One
327or more source code files contain the actual implementation(s) of each object.
328
329The objects shown above are:
330
331* Main controller: buffer controller for the subsampled-data buffer, which
332 holds the preprocessed input data. This controller invokes preprocessing to
333 fill the subsampled-data buffer, and JPEG compression to empty it. There is
334 usually no need for a full-image buffer here; a strip buffer is adequate.
335
336* Preprocessing controller: buffer controller for the downsampling input data
337 buffer, which lies between colorspace conversion and downsampling. Note
338 that a unified conversion/downsampling module would probably replace this
339 controller entirely.
340
341* Colorspace conversion: converts application image data into the desired
342 JPEG color space; also changes the data from pixel-interleaved layout to
343 separate component planes. Processes one pixel row at a time.
344
345* Downsampling: performs reduction of chroma components as required.
346 Optionally may perform pixel-level smoothing as well. Processes a "row
347 group" at a time, where a row group is defined as Vmax pixel rows of each
348 component before downsampling, and Vk sample rows afterwards (remember Vk
349 differs across components). Some downsampling or smoothing algorithms may
350 require context rows above and below the current row group; the
351 preprocessing controller is responsible for supplying these rows via proper
352 buffering. The downsampler is responsible for edge expansion at the right
353 edge (i.e., extending each sample row to a multiple of 8 samples); but the
354 preprocessing controller is responsible for vertical edge expansion (i.e.,
355 duplicating the bottom sample row as needed to make a multiple of 8 rows).
356
357* Coefficient controller: buffer controller for the DCT-coefficient data.
358 This controller handles MCU assembly, including insertion of dummy DCT
359 blocks when needed at the right or bottom edge. When performing
360 Huffman-code optimization or emitting a multiscan JPEG file, this
361 controller is responsible for buffering the full image. The equivalent of
362 one fully interleaved MCU row of subsampled data is processed per call,
363 even when the JPEG file is noninterleaved.
364
365* Forward DCT and quantization: Perform DCT, quantize, and emit coefficients.
366 Works on one or more DCT blocks at a time. (Note: the coefficients are now
367 emitted in normal array order, which the entropy encoder is expected to
368 convert to zigzag order as necessary. Prior versions of the IJG code did
369 the conversion to zigzag order within the quantization step.)
370
371* Entropy encoding: Perform Huffman or arithmetic entropy coding and emit the
372 coded data to the data destination module. Works on one MCU per call.
373 For progressive JPEG, the same DCT blocks are fed to the entropy coder
374 during each pass, and the coder must emit the appropriate subset of
375 coefficients.
376
377In addition to the above objects, the compression library includes these
378objects:
379
380* Master control: determines the number of passes required, controls overall
381 and per-pass initialization of the other modules.
382
383* Marker writing: generates JPEG markers (except for RSTn, which is emitted
384 by the entropy encoder when needed).
385
386* Data destination manager: writes the output JPEG datastream to its final
387 destination (e.g., a file). The destination manager supplied with the
388 library knows how to write to a stdio stream; for other behaviors, the
389 surrounding application may provide its own destination manager.
390
391* Memory manager: allocates and releases memory, controls virtual arrays
392 (with backing store management, where required).
393
394* Error handler: performs formatting and output of error and trace messages;
395 determines handling of nonfatal errors. The surrounding application may
396 override some or all of this object's methods to change error handling.
397
398* Progress monitor: supports output of "percent-done" progress reports.
399 This object represents an optional callback to the surrounding application:
400 if wanted, it must be supplied by the application.
401
402The error handler, destination manager, and progress monitor objects are
403defined as separate objects in order to simplify application-specific
404customization of the JPEG library. A surrounding application may override
405individual methods or supply its own all-new implementation of one of these
406objects. The object interfaces for these objects are therefore treated as
407part of the application interface of the library, whereas the other objects
408are internal to the library.
409
410The error handler and memory manager are shared by JPEG compression and
411decompression; the progress monitor, if used, may be shared as well.
412
413
414*** Decompression object structure ***
415
416Here is a sketch of the logical structure of the JPEG decompression library:
417
418 |-- Entropy decoding
419 |-- Coefficient controller --|
420 | |-- Dequantize, Inverse DCT
421Main controller --|
422 | |-- Upsampling
423 |-- Postprocessing controller --| |-- Colorspace conversion
424 |-- Color quantization
425 |-- Color precision reduction
426
427As before, this diagram also represents typical control flow. The objects
428shown are:
429
430* Main controller: buffer controller for the subsampled-data buffer, which
431 holds the output of JPEG decompression proper. This controller's primary
432 task is to feed the postprocessing procedure. Some upsampling algorithms
433 may require context rows above and below the current row group; when this
434 is true, the main controller is responsible for managing its buffer so as
435 to make context rows available. In the current design, the main buffer is
436 always a strip buffer; a full-image buffer is never required.
437
438* Coefficient controller: buffer controller for the DCT-coefficient data.
439 This controller handles MCU disassembly, including deletion of any dummy
440 DCT blocks at the right or bottom edge. When reading a multiscan JPEG
441 file, this controller is responsible for buffering the full image.
442 (Buffering DCT coefficients, rather than samples, is necessary to support
443 progressive JPEG.) The equivalent of one fully interleaved MCU row of
444 subsampled data is processed per call, even when the source JPEG file is
445 noninterleaved.
446
447* Entropy decoding: Read coded data from the data source module and perform
448 Huffman or arithmetic entropy decoding. Works on one MCU per call.
449 For progressive JPEG decoding, the coefficient controller supplies the prior
450 coefficients of each MCU (initially all zeroes), which the entropy decoder
451 modifies in each scan.
452
453* Dequantization and inverse DCT: like it says. Note that the coefficients
454 buffered by the coefficient controller have NOT been dequantized; we
455 merge dequantization and inverse DCT into a single step for speed reasons.
456 When scaled-down output is asked for, simplified DCT algorithms may be used
457 that need fewer coefficients and emit fewer samples per DCT block, not the
458 full 8x8. Works on one DCT block at a time.
459
460* Postprocessing controller: buffer controller for the color quantization
461 input buffer, when quantization is in use. (Without quantization, this
462 controller just calls the upsampler.) For two-pass quantization, this
463 controller is responsible for buffering the full-image data.
464
465* Upsampling: restores chroma components to full size. (May support more
466 general output rescaling, too. Note that if undersized DCT outputs have
467 been emitted by the DCT module, this module must adjust so that properly
468 sized outputs are created.) Works on one row group at a time. This module
469 also calls the color conversion module, so its top level is effectively a
470 buffer controller for the upsampling->color conversion buffer. However, in
471 all but the highest-quality operating modes, upsampling and color
472 conversion are likely to be merged into a single step.
473
474* Colorspace conversion: convert from JPEG color space to output color space,
475 and change data layout from separate component planes to pixel-interleaved.
476 Works on one pixel row at a time.
477
478* Color quantization: reduce the data to colormapped form, using either an
479 externally specified colormap or an internally generated one. This module
480 is not used for full-color output. Works on one pixel row at a time; may
481 require two passes to generate a color map. Note that the output will
482 always be a single component representing colormap indexes. In the current
483 design, the output values are JSAMPLEs, so an 8-bit compilation cannot
484 quantize to more than 256 colors. This is unlikely to be a problem in
485 practice.
486
487* Color reduction: this module handles color precision reduction, e.g.,
488 generating 15-bit color (5 bits/primary) from JPEG's 24-bit output.
489 Not quite clear yet how this should be handled... should we merge it with
490 colorspace conversion???
491
492Note that some high-speed operating modes might condense the entire
493postprocessing sequence to a single module (upsample, color convert, and
494quantize in one step).
495
496In addition to the above objects, the decompression library includes these
497objects:
498
499* Master control: determines the number of passes required, controls overall
500 and per-pass initialization of the other modules. This is subdivided into
501 input and output control: jdinput.c controls only input-side processing,
502 while jdmaster.c handles overall initialization and output-side control.
503
504* Marker reading: decodes JPEG markers (except for RSTn).
505
506* Data source manager: supplies the input JPEG datastream. The source
507 manager supplied with the library knows how to read from a stdio stream;
508 for other behaviors, the surrounding application may provide its own source
509 manager.
510
511* Memory manager: same as for compression library.
512
513* Error handler: same as for compression library.
514
515* Progress monitor: same as for compression library.
516
517As with compression, the data source manager, error handler, and progress
518monitor are candidates for replacement by a surrounding application.
519
520
521*** Decompression input and output separation ***
522
523To support efficient incremental display of progressive JPEG files, the
524decompressor is divided into two sections that can run independently:
525
5261. Data input includes marker parsing, entropy decoding, and input into the
527 coefficient controller's DCT coefficient buffer. Note that this
528 processing is relatively cheap and fast.
529
5302. Data output reads from the DCT coefficient buffer and performs the IDCT
531 and all postprocessing steps.
532
533For a progressive JPEG file, the data input processing is allowed to get
534arbitrarily far ahead of the data output processing. (This occurs only
535if the application calls jpeg_consume_input(); otherwise input and output
536run in lockstep, since the input section is called only when the output
537section needs more data.) In this way the application can avoid making
538extra display passes when data is arriving faster than the display pass
539can run. Furthermore, it is possible to abort an output pass without
540losing anything, since the coefficient buffer is read-only as far as the
541output section is concerned. See libjpeg.txt for more detail.
542
543A full-image coefficient array is only created if the JPEG file has multiple
544scans (or if the application specifies buffered-image mode anyway). When
545reading a single-scan file, the coefficient controller normally creates only
546a one-MCU buffer, so input and output processing must run in lockstep in this
547case. jpeg_consume_input() is effectively a no-op in this situation.
548
549The main impact of dividing the decompressor in this fashion is that we must
550be very careful with shared variables in the cinfo data structure. Each
551variable that can change during the course of decompression must be
552classified as belonging to data input or data output, and each section must
553look only at its own variables. For example, the data output section may not
554depend on any of the variables that describe the current scan in the JPEG
555file, because these may change as the data input section advances into a new
556scan.
557
558The progress monitor is (somewhat arbitrarily) defined to treat input of the
559file as one pass when buffered-image mode is not used, and to ignore data
560input work completely when buffered-image mode is used. Note that the
561library has no reliable way to predict the number of passes when dealing
562with a progressive JPEG file, nor can it predict the number of output passes
563in buffered-image mode. So the work estimate is inherently bogus anyway.
564
565No comparable division is currently made in the compression library, because
566there isn't any real need for it.
567
568
569*** Data formats ***
570
571Arrays of pixel sample values use the following data structure:
572
573 typedef something JSAMPLE; a pixel component value, 0..MAXJSAMPLE
574 typedef JSAMPLE *JSAMPROW; ptr to a row of samples
575 typedef JSAMPROW *JSAMPARRAY; ptr to a list of rows