home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include "png.h"
-
- // Requires: libpng, zlib, ANSI (4i) C lib's
-
- #include <Files.h>
- #include <Memory.h>
-
- PicHandle ReadPGN(FSSpec *sfFilePtr)
-
- { OSErr err = noErr;
- short savedVol;
- Str31 name;
-
- png_struct read_ptr;
- png_info info_ptr;
- png_info end_info;
- FILE *fpin;
- png_byte *row_buf;
- png_uint_32 rowbytes;
- png_uint_32 y, x;
- int channels, num_pass, pass;
- PicHandle myPic = nil;
-
-
- BlockMoveData((Ptr)(sfFilePtr.name), (Ptr)name, sizeof(Str31));
-
- err = GetVol(0, &savedVol);
- if (err == noErr)
- {
- err = HSetVol(0, sfFilePtr->vRefNum, sfFilePtr->parID);
- if (err == noErr)
- {
- p2cstr(name);
-
- row_buf = (png_byte *)0;
-
- fpin = fopen((char *) name, "rb");
- if (!fpin) {
- // fprintf(STDERR, "Could not find input file %s\n", inname);
- return -1;
- }
-
- if (setjmp(read_ptr.jmpbuf)) {
- // fprintf(STDERR, "libpng read error\n");
- fclose(fpin);
- return -2;
- }
-
- png_read_init(&read_ptr);
- png_info_init(&info_ptr);
-
- png_init_io(&read_ptr, fpin);
-
- png_read_info(&read_ptr, &info_ptr);
-
- #if OutputInfo /* RMF */
- fprintf(STDERR, "%s, Width = %d, Height = %d, Depth = %d\n",
- inname, info_ptr.width, info_ptr.height, info_ptr.bit_depth);
- fprintf(STDERR, "Color type = %d, interlace_type = %d\n",
- info_ptr.color_type, info_ptr.interlace_type);
- #endif
-
- if ((info_ptr.color_type & 3) == PNG_COLOR_MASK_COLOR)
- channels = 3;
- else channels = 1;
-
- if (info_ptr.color_type & PNG_COLOR_MASK_ALPHA)
- channels++;
-
- rowbytes = ((info_ptr.width * info_ptr.bit_depth * channels + 7) >> 3);
- row_buf = (png_byte *)malloc((size_t)rowbytes);
- if (!row_buf) {
- fprintf(STDERR, "no memory to allocate row buffer\n");
- png_read_destroy(&read_ptr, &info_ptr, (png_info *)0);
- fclose(fpin);
- return -3;
- }
-
- if (info_ptr.interlace_type) {
- num_pass = png_set_interlace_handling(&read_ptr);
- } else {
- num_pass = 1;
- }
-
-
- for (pass = 0; pass < num_pass; pass++)
- {
- for (y = 0; y < info_ptr.height; y++)
- {
- png_read_rows(&read_ptr, &row_buf, (png_byte **)0, 1); // Read one row of image data
- }
- }
-
- png_read_end(&read_ptr, &end_info);
- png_read_destroy(&read_ptr, &info_ptr, &end_info);
-
- fclose(fpin);
-
- x = info_ptr.width;
- y = info_ptr.height;
-
- if (info_ptr.bit_depth == 24) {
- rowbytes = (x * 4L); // Make Multiple of 4 bytes (32bit RGB image)
- } else {
-
- ByteScanLine = (((x * (unsigned long) info_ptr.bit_depth) + 7L) / 8L); /* Make Multiple of byte */
- }
-
- // info_ptr.color_type =
- // PNG_COLOR_TYPE_PALETTE
- // PNG_COLOR_TYPE_RGB
- // PNG_COLOR_TYPE_GRAY
- // PNG_COLOR_TYPE_RGB_ALPHA
- // PNG_COLOR_TYPE_GRAY_ALPHA
-
- // Black & White Image
-
- if (info_ptr.bit_depth == 1) {
- BitMap theBits;
-
- theBits.baseAddr = (Ptr) row_buf; // Set up new BitMap
- theBits.rowBytes = rowbytes; // width of image
- SetRect(&(theBits.bounds), 0, 0, x, y);
-
- myPic = MakePictFromBW(&theBits); // create a PicHandle from B&W BitMap
-
- // Cleanup and Exit.
- } else {
-
- CTabHandle macCtabHandle = nil;// Color Table for 2, 4, 8 bit images
- PixMap srcBits;
-
-
- if (info_ptr.bit_depth >= 2 && info_ptr.bit_depth <= 8) {
- if (info_ptr.valid & PNG_INFO_PLTE) {
- info_ptr.palette;
- info_ptr.num_palette;
- macCtabHandle = nil; // Get the color table...
- }
- }
-
- // See: QuickDraw.h
- // Setup PixMap data structure:
- srcBits.baseAddr = row_buf; // ptr to the Pixcell data
- // offset to next scan line
- srcBits.rowBytes = rowbytes | 0x8000; // pixmap (4, 8, 16 or 24/32bit image)
-
- srcBits.bounds.top = 0; // encloses bitmap
- srcBits.bounds.left = 0;
- srcBits.bounds.bottom = y;
- srcBits.bounds.right = x;
- srcBits.pmVersion = 0; // pixMap version number
-
- srcBits.packType = 1; // defines packing format: 1 = direct
-
- srcBits.packSize = 0L; // length of pixel data
- srcBits.hRes = 0x480000; // 72dpi fixed point
- srcBits.vRes = 0x480000; // vert. resolution (ppi)
- srcBits.planeBytes = 0L; // offset to next plane
-
- srcBits.pmTable = macCtabHandle; // color map for this pixMap
- srcBits.pmReserved = 0;
-
- if (info_ptr.bit_depth == 24) { // RGB data 24bit color, no Color Table
- srcBits.pixelType = RGBDirect;
- srcBits.pixelSize = 32; // # bits in pixel
- srcBits.cmpCount = 3; // # components in pixel (R,G,B)
- srcBits.cmpSize = 8; // # bits per component (3 * 8) =
- // 24bits + 8bits pad = 32 bits
-
- } else {
-
- // Else: 4bit or 8bit color image
- srcBits.pixelType = 0;
- srcBits.pixelSize = info_ptr.bit_depth; // # bits in pixel
- srcBits.cmpCount = 1; // # components in pixel
- srcBits.cmpSize = info_ptr.bit_depth; // # bits per component
- }
-
-
- myPic = CreatePICT2( &srcBits, &srcBits.bounds, &srcBits.bounds, ditherCopy);
-
- if (srcBits.pmTable) DisposHandle((Handle) srcBits.pmTable); // Free Color table allocated
-
-
- }
-
- /*------------ */
-
- free(row_buf);
- SetVol(0, savedVol);
- return myPic;
- } // End readPNG()