Re: [GD-DEVEL] [proposal] Attach DIB section buffer to gdImage
[email protected] ("Pierre Joye")
| Newsgroups | php.gd.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Markus, On Feb 13, 2008 3:46 PM, Markus Fleck-Graffe <[email protected]> wrote: > Pierre Joye wrote: > >>> I'm finishing the initial support of the new formats. The two most > >>> important additions for you and other users are the true 8bit per > >>> channel (alpha) and the contiguous buffer instead of per row > >>> allocation. It will let you use a DIB/BMP (or any compatible buffer) > >>> directly without any extra allocations or loop. It will require a lof > >>> tests and work to get stable enough for 2.1.x :) > > There is this very powerful "iterator" abstraction used, for example, > by the Fltk GUI toolkit, and by Python's "NumPy" matrix calculation > library as well[1]. > > It supports basically all kinds of contiguous buffer schemes (including > the Windows DIB one), and has excellent performance characteristics. > > Basically, you store the following data for each image: > - "topleft": a pointer to the memory location that stores the first > (top-left) pixel of the image > - "buffer": a pointer to the (contiguous) memory buffer (which will > be used mainly just for eventually free()'ing the buffer) > - "depth": pixel depth (in bytes, or maybe even in bits), > e.g. 3 (bytes) for plain 24-bit RGB, or 4 (bytes) for 32-bit RGBA > - "w", "h": actual (logical) image width and height (in pixels) > - "dy" byte offset to the next scan line (for "vertical" iteration) > - "dx" byte offset to the next pixel (for "horizontal" iteration) > > Ideally, for a contiguous RGB(A) buffer, "dx" would be equal > to "depth", "dy" would be equal to "width", and "topleft" would > be equal to "buffer". > > Now: > - if scanlines must be "padded" to satisfy some alignment constraints, > "dy" may be made larger than "width" > - in case of "upside-down" storage (such as with Windows DIB bitmaps), > "dy" must be made negative, and the initial image pointer ("topleft") > must be calculated to point to the beginning of the "last" DIB > scanline in memory (which is actually the "topmost" scanline of > the corresponding image). > > The memory position of each pixel can then be calculated at any > time, using either absolute or relative pointer arithmetics, > based only on the above small (and fixed) set of metadata. That's more or less what I'm doing except that the various informations depend of the image format you use. I think adding such internal structure can make GD flexible enough to work with almost every system out there. To full fill the needs, we also have to add different alpha support: - level of transparency or opacity - pre multiplied alpha or not - rgba masks (obviously do not apply to gray level images) > It is also possible to very efficiently (and safely) perform > BITBLT-style operations using fast block copy operations, just by > calculating the corresponding topleft/width/height/dx/dy values, > for any rectangular region inside an image. (In fact, multiple > overlapping images could even share the same data buffer, > which may be useful e.g. for showing a scrollable rectangular > clipped "view" of a larger image in a GUI toolkit, as Fltk can, > or for processing very large 2D arrays or matrices, as NumPy can.) You can copy only a row at a time using system fast block copy as soon as the buffer are not contiguous.That's why I would love to have a contiguous buffer, you don't need much offsets but stride. I have now to take a look at these implementations, they seem to cover all we need! > Now the question is: are there any GD users who depend on the > peculiarities and availability of the current tpixels array > (probably for non-contiguous in-memory images whose buffers > have not been created by GD itself)? Would it be an option > to get rid of "tpixels" for GD 3.x, for the sake of > significantly improving performance? That's the second main reason behind the new formats, the first being interoperability with other libraries or toolkits. Many users depend on the presence of tpixel (and the palette buffers), I'm not sure we gain much to remove it. But if we do, as you said, we can do it in 3.x. Almost all new rendering functions will work only in the new formats and not with the current 31bit (7,8,8,8) format and with level of opacity instead of transparency as it is now (more logical and works well with other toolkits). Thanks for this post, it is really what we need to implement the best possible solution in GD (or closed to the best :). Cheers, -- Pierre http://blog.thepimp.net | http://www.libgd.org