2010.05.11 16:59 "[Tiff] Combining multiple G4 images into a single output image", by Richard Nolde

2010.05.11 17:33 "Re: [Tiff] Combining multiple G4 images into a single output image", by Oliver Geisen

Hello Richard,

could handle YCbCr compressed data. From what I remember, libtiff is going to read a whole strip anyway and then hand off a scanline at a time as your read from the strip even if you call TIFFReadScanline.

I also thought that libtiff is doing it that way. Because my tool should handle G4 compressed data only it must read a coded strip, decode it, and hand out the scanlines one by one. I'm also aware that there is no random access to the scanlines, but i don't need this anyway.

Depending on the size of your final image, you may have to allocate a working buffer that is only as large as a few scanlines, ideally the size of a full strip in the output image rather than creating the full output image in memory before writing any of it out. This assumes all your input images will be pasted into the output buffer from left to right and the final image will be N * the width of the input images but only 1 * the height of the input image. If you have multiple rows and columns of subimages in the output image, you have to calculate the width of the widest subset and pad every scanline to match.

I really thougt about reading the background image into memory and then read file by file to be placed and overwrite the background with their data at the given positions. Therefore i need to crop the lines to the width of the background (if they would float out to the right) and mask/shift if the placement is not on a byte boundary. Because of the high resolution of the image (1270dpi) i really don't think anybody would notice a displacement if round the x-value up or down to the next byte boundary. This would make a maximum error of 7 1270/inch wich are only about a tenth of a millimeter. Maybe i should at this as an option ("--turbo").

Reading non-byte-aligned samples is required to crop or combine images that are not a multiple of 8 bits per scanline but you will have to track the byte AND bit offsets across multiple input images when you paste the input scanlines into your output buffer. I only have to deal with that within a single source image. If you are reading a scanline at a time, it should not be too hard for Bilevel data.

  I am thinking about some code to speed up the masking operation but haven't written anything yet.

In the case of merging/overlaping two pictures at bilevel, and the image on top is not placed at a byte boundary you need to mask and combine only the edges of the images, the fully overlapping part then only needs bit shifting. I'm not really shure what it means to do such massive shifting operations. It really depends on the size of the images to be placed. Maybe it could be optimized by calculating what is really seen later of the image to be placed and just skip full bytes which would be overwritten by images placed later. I also can think of some lookup-tables to aid masking and shifting. One LT could get a byte value multiplied with a shiftcount, building a pointer and just read back the precalculated value. This LT could be build on runtime by a function. This way no real shifting had to be done, but only lookups which may be much faster.

The same technique could be used to masking. The pointer could be calced by the original value and a mask value (saying: mask 0x54 with &b11110000). Such a table should not be larger than 256x256 bytes (64k).

Regarding memory mapped files. There may be greater benefit for memory mapping in cases where an image is being rotated since access to the source data will require multiple passes through a given scanline.

For now i don't need to support rotating, not even mirroring.

Oliver.