diff options
Diffstat (limited to 'doc/Imgbuf.txt')
-rw-r--r-- | doc/Imgbuf.txt | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/doc/Imgbuf.txt b/doc/Imgbuf.txt new file mode 100644 index 00000000..1039ff9e --- /dev/null +++ b/doc/Imgbuf.txt @@ -0,0 +1,177 @@ +Aug 2004, S.Geerken@ping.de + +============= +Image Buffers +============= + +General +======= + +Image buffers depend on the platform (see DwRender.txt), but have a +general, platform independant interface, which is described in this +section. The next section describes the Gdk version of Imgbuf. + +The structure ImgBuf will become part of the image processing, between +image data decoding and the widget DwImage. Its purposes are + + 1. storing the image data, + 2. handling scaled versions of this buffer, and + 3. drawing. + +The latter must be done independently from the window. + +Storing Image Data +------------------ +Imgbuf supports five image types, which are listed in the table +below. The representation defines, how the colors are stored within +the data, which is passed to a_Imgbuf_copy_row(). + + | bytes per | + type | pixel | representation + ---------------+-----------+------------------------- + RGB | 3 | red, green, blue + RGBA | 4 | red, green, blue, alpha + gray | 1 | gray value + indexed | 1 | index to colormap + indexed alpha | 1 | index to colormap + +The last two types need a colormap, which is set by +a_Imgbuf_set_cmap(), which must be called before +a_Imgbuf_copy_row(). This function expects the colors as 32 bit +unsigned integers, which have the format 0xrrbbgg (for indexed +images), or 0xaarrggbb (for indexed alpha), respectively. + +Scaling +------- +The buffer with the original size, which was created by +a_Imgbuf_new(), is called root buffer. Imgbuf provides the ability to +scale buffers. Generally, both root buffers, as well as scaled +buffers, may be shared, memory management is done by reference +counters. + +Via a_Imgbuf_get_scaled_buf(), you can retrieve a scaled buffer. The +way, how this function works in detail, is described in the code, but +generally, something like this works always, in an efficient way: + + old_buf = cur_buf; + cur_buf = a_Imgbuf_get_scaled_buf(old_buf, with, height); + a_Imgbuf_unref (old_buf); + +Old_buf may both be a root buffer, or a scaled buffer. + +(As an exception, there should always be a reference on the root +buffer, since scaled buffers cannot exist without the root buffer, but +on the other side, do not hold references on it. So, if in the example +above, old_buf would be a root buffer, and there would, at the +beginning, only be one reference on it, new_buf would also be +destroyed, along with old_buf. Therefore, an external reference must +be added to the root buffer, which is in dillo done within the dicache +module.) + +The root buffer keeps a list of all children, and all operations +operating on the image data (a_Imgbuf_copy_row() and +a_Imgbuf_set_cmap()) are delegated to the scaled buffers, when +processed, and inherited, when a new scaled buffer is created. This +means, that they must only be performed for the root buffer. + +Drawing +------- +There are two situations, when drawing is necessary: + + 1. To react on expose events, the function a_Imgbuf_draw() can be + used. Notice that the exact signature of this function is + platform dependant. + + 2. When a row has been copied, it has to be drawn. To determine the + area, which has to be drawn, the function + a_Imgbuf_get_row_area() should be used. In dillo, the dicache + module will first call a_Img_copy_row(), and then call + a_Dw_image_draw_row() for the images connected to this image + buffer. a_Dw_image_draw_row() will then call + p_Dw_widget_queue_draw(), with an area determined by + a_Imgbuf_get_row_area(). + + +The Gdk Implementation +====================== + +The Gdk implementation is used by the Gtk+ platform. [... todo] + + +Global Scalers +============== + +In some cases, there is a context, where images have to be scaled +often, by a relatively constant factor. For example, the preview +window (GtkDwPreview) draws images via the Imgbuf draw functions, but +uses scaled buffers. Scaling such a buffer each time it is needed, +causes huge performance losses. On the other hand, if the preview +window would keep these scaled buffers (e.g. by lazy mapping of the +original buffer to the scaled buffer), the scaled buffers get never +freed, since the view is not told about, when the original buffer is +not needed anymore. (n.b., that currently, the scaled buffers are +destroyed, when the original buffer is destroyed, but this may change, +and even this would leave "zombies" in this mapping structure, where +the values refer to dead pointers). + +It is sufficient, that references on the scaled buffers are referred +somehow, so that they do not get destroyed between different +usages. The caller (in this case the preview) simply requests a scaled +buffer, but the Imgbuf returns this from the list of already scaled +buffers. + +These references are hold by special structures, which are called +"scalers". There are two types of scalers, local scalers, which are +bound to image buffers, and global scalers, which refer to multiple +scalers. + +What happens in different situations: + + - The caller (e.g. the preview) requests a scaled buffer. For this, + it uses a special method, which also passes the global image + scaler, which was created before (for the preview, there is a 1-1 + association). The Imgbuf uses this global image scaler, to + identify the caller, and keeps a list of them. If this global + scaler is not yet in the list, it is added, and a local scaler is + created. + + + + - + +There are three images in the page, i1a, i1b, and i2. I1a and i1b +refer to the same image recource, represented by the root image buffer +iba, which original size is 200 x 200. I1a is displayed in original +size, while i1b is displayed at 100 x 100. I2 refers to an other +recource, ibb, which has the size 300 x 300. I2 is shown in original +size. + + + :DwRenderLayout ------------------- :DwPage ----------. + / \ | + ,----' `----. ,------ i1a:DwImage --+ + / \ | | + view1:GtkDwViewport view2:GtkDwPreview | ,---- i1b:DwImage --| + | | | | + ,------------------------------' | | ,-- i2: DwImage --' + | | | | + | ,-------------------------------------' | | + | | ,--------------------------------' | + | | | ,----' + | | | | + | V | V + | iba:Imgbuf | ibb:Imgbuf -- 30x30 + | | | V | ^ + | | +- 100x100 ,- 20x20 ,- 10x10 | | + | | | | ^ | ^ | | + | | `----------+----|---' | `--. ,--' + | | ,--------------' | | | + | | | ,------------------' | | + | | | | | | + | lca:ImgbufLSc lcb:ImgbufLSc + | (factor 1/10) (factor 1/10) + | \ / + | `-----------. ,-------------------' + | \ / + `------------------> scl:ImgbufGSc + (factor 1/10) |