• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Creating Really Big TIFF's
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Creating Really Big TIFF's


  • Subject: Re: Creating Really Big TIFF's
  • From: Thomas Finley <email@hidden>
  • Date: Thu, 10 Jul 2003 13:53:25 -0400

On Thursday, July 10, 2003, at 07:47 AM, Robert Clair wrote:
Since this is potentially hundreds of Mbytes, just making an NSImage with
a correct size NSImageRep, drawing on it and using -TiffRepresentation
isn't going to fly. (Can't assume the user has a G5 with 8 gig
of memory :-) )

It may with virtual memory if it is indeed hundreds and _not_ thousands of megabytes, of course, but it would be deathly slow and best avoided since it is unnecessary.

The last time I had to do something like this (years go, X11, Sun)
I banded the image, created PostScript files for the bands and
then post-processed them through a hacked up version of
GhostScript to produce targa files (what was needed for the job)
and some code to sew the tga's together.

Gross. :)

Is there some way to make Cocoa do the banding ? It must
be able to do something like this because you can print. I suspect
what I need is a dummy printer that specifies the page size and resolution
and accepts the pixels, which it will stream to a file. Raw pixels and
fixing up into tiff or whatever as a post process is OK.
Any suggestions on where to look for the info ?

Given how you're going about this, the easiest way I can think of is to _not_ use Cocoa's image hadling for this sort of job. Install something like libtiff, which will allow you to write segmented tiffs without needing to hold absolutely everything in memory. Provided you can easily segment the image, this is a very trivial procedure; much easier than hacking ghostscript and sewing together different image files yourself, at any rate. :)

I installed my libtiff via fink. Linking of libraries defaults to dynamic of course; if this is something you're going to be distributing to other people that you can't depend on having libtiff, you can build by including the libraries for libtiff.a, libjpeg.a as you would any object file when you build your app, and link in -lz.) See http://www.libtiff.org/ for more info, including copyright restrictions (happily very unrestrictive). Tutorials abound on the web by searching for libtiff on Google.

The source following is an example use of libtiff. It writes out the images in strips (horizontal bars, the first at the top, the last on the bottom), so that you need hold only the data for one strip in memory at a time. The strips are 8 pixels heigh. Each strip is set to a different solid color (red, green, blue, and repeat) and written to the TIFF file handle. I tried to make my program more obvious and concise than speedily efficient. In addition to strips (segmented along y axis) you can use tiles (segmented along x and y axis).

You may find it better to use tiles, not strips. Tiles are like strips, except, as their name implies, they're segmented in the x and y axes and not just the y axis like strips. See the libtiff docs for more info.

Note that, with the right format flags for NSBitmapImageRep (to match 8 bits per sample and 3 sample per pixel and the rest), you could pass its [rep bitmapData] instead of "raster" for each strip, and use Cocoa's image and graphics routines for creating the pixel data for each strip (or tile) and use libtiff for writing each strip (or tile).

==========

#include <stdio.h>
#include <tiffio.h>

#define WIDTH 150
#define HEIGHT 200
#define SAMPLES 3
#define ROWSPERSTRIP 8

uint8 Colors[] = { 255, 0, 0, /* Red */
0, 160, 0, /* Green */
0, 0, 200 }; /* Blue. */
unsigned DifferentColors = 3;

int main() {
tstrip_t s, strips; /* These are really just unsigned ints. */
tsize_t stripSize = WIDTH*ROWSPERSTRIP*SAMPLES; /* size_ts, really. */
TIFF *image;

/* Create the tiff to write to. */
if ((image = TIFFOpen("testwrite.tiff", "w")) == NULL) {
fprintf(stderr, "Could not open file to write.\n");
exit(1);
}

/* Set tags. */
TIFFSetField(image, TIFFTAG_IMAGEWIDTH, WIDTH);
TIFFSetField(image, TIFFTAG_IMAGELENGTH, HEIGHT);
TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, 3);
TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, ROWSPERSTRIP);
TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
/* You say you want 600 dpi */
TIFFSetField(image, TIFFTAG_XRESOLUTION, 600.0);
TIFFSetField(image, TIFFTAG_YRESOLUTION, 600.0);
TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);

/* Write the info to a file. */
strips = HEIGHT / ROWSPERSTRIP;
for (s=0; s<strips; s++) {
/* Create the strip... sets a strip to a single block of color */
unsigned i, currentColor = s % DifferentColors; /* Which color? */
uint8 raster[WIDTH * ROWSPERSTRIP * SAMPLES]; /* Buffer for strip */
for (i=0; i<stripSize; i++) /* Set pixels. */
raster[i] = Colors[(currentColor*SAMPLES) + (i%SAMPLES)];
/* Write the current strip to the file */
if (TIFFWriteEncodedStrip(image, s, raster, stripSize) != stripSize)
fprintf(stderr, "Could not write %d bytes on strip %d", stripSize, s);
}

/* Close it up. */
TIFFClose(image);
return 0;
}
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

References: 
 >Creating Really Big TIFF's (From: Robert Clair <email@hidden>)

  • Prev by Date: Complex NSCells in an NSTableView
  • Next by Date: Re: Complex NSCells in an NSTableView
  • Previous by thread: Re: Creating Really Big TIFF's
  • Next by thread: Re: Creating Really Big TIFF's
  • Index(es):
    • Date
    • Thread