THIS DOCUMENT IS OBSOLETED BY THE AUTOLAYERS MERGE * Paint devices and painters Chalk's core consists of paint devices and painters: KisPaintDevice KisPainter These classes are (very) loosely modelled on QPaintDevice and QPainter. KisPaintDevice also takes up some of the roles of TQImage, but isn't all that efficient at it. This is a write-up of my (Boudewijn's) understanding at this point; * Getting pixel data in and out of a KisPaintDevice. Chalk stores all image data in tiles; the tiles are managed by the aptly named KisTileMgr. Inside the tiles, we have a KisPixelData structure, which is basically a wrapper that packs together a pointer to a memory area that contains the pixel data (QUANTUM's) and some more information. Ordinarily, you will change the data inside a KisPaintDevice through the KisPainter. Using KisPainter has the advantage that your changes will be undoable and that the tile manager is hidden. That's especially nice, since you generally don't want to work directly with tiles, not before having bought shares in an aspirin producer. The other way of messing with the pixels inside a KisPaintDevice is through the pixel() and and setPixel() methods in KisPaintDevice. These methods retrieve and set the specified pixel data using the tiles, but are not undoable. They are also rather ineffcient and slow. KisPainter and KisPaintDevice do the job of hiding the actual image data from the chalk hacker, but sometimes it's not enough, sometimes you need to loop over all the pixels in an image, do something, and write the pixels back to this or another image (or sections of images). In the near future, we will offer an iterator over the pixels, for now you will have to ask the tile manager to copy all the bytes of the image data in a buffer for you to read. Likewise, in the future we will hopefully have something clever to feed pixel data to the tile manager. For now, you will have to fill a memory buffer with the desired data and feed that to the tile manager. ** Getting pixel data into your buffer Define a pointer to a memory buffer with QUANTUMS QUANTUM *buf; Create the buffer. Note that you cannot assume that there is one byte per channel; QUANTUM can be bigger. buf = new QUANTUM[width * height * depth * sizeof(QUANTUM)]; Fill the buf with the data. x1, y1, x2, y2 are the top left and bottom right corner of the section you want. stride is the width of the section in bytes, i.e. (x2 - x1 + 1) * depth. Note that stride does not need to be pre-multiplied with sizeof(QUANTUM), apparently. tilemgr -> readPixelData(x1, y1, x2, y2, buf, stride); Now all the pixels in the tile manager are copied into 'buf' -- the operative word is 'copy', which means slow, and takes a lot of memory is the section is big. If you can stand computing with tiles, you can copy each tile into the buffer, which takes a lot less memory, but you have to take care when the image isn't exactly a multiple of the tilesize. See kis_image_magick_converter.cpp for an example. ** Getting your data into a KisPaintDevice without using KisPainter Although in the future we might offer a bitBlt that takes a simple memory buffer and blits that onto the paint device, for now, you will have to access the tile manager directly, using writePixelData. First create a buffer, just as above: QUANTUM * newData = new QUANTUM[width * height * depth * sizeof(QUANTUM)]; But unless you are sure you are going to fill absolutely every pixel, you might want to initialize the buffer with memset. Chalk, in contrast with ImageMagick, uses 0 as the value for transparent opacity, so that's nice: memset(newData, width * height * depth * sizeof(QUANTUM), 0); Then create a new tilemanager, or reuse the old one if the size is still correct. Stride is again width * depth, not width * depth * sizeof(QUANTUM) KisTileMgrSP tm = new KisTileMgr(depth, width, height); tm -> writePixelData(x1, y1, x2, y2, newData, stride);