/* This file is part of Netpbm Formats, a File Format plugin for Adobe Photoshop Copyright (C) 2004-6 Toby Thain, toby@telegraphics.com.au This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "file_io.h" #include "pbm.h" extern int chunk; char *outdata; int top; unsigned fix16(unsigned x); void nextchunk(FormatRecordPtr pb){ if(top+chunk > pb->imageSize.v) chunk = pb->imageSize.v - top; pb->theRect.left = 0; pb->theRect.right = pb->imageSize.h; pb->theRect.top = top; pb->theRect.bottom = top+chunk; pb->data = outdata; } OSErr write_start(FormatRecordPtr pb){ OSErr e; char s[32]; int n,subformat,rb; long m; switch(pb->imageMode){ case plugInModeBitmap: subformat = PBM_KEY; break; case plugInModeGrayScale: case plugInModeGray16: subformat = PGM_KEY; break; case plugInModeRGBColor: case plugInModeRGB48: subformat = PPM_KEY; break; default: return formatBadParameters; } n = sprintf(s,"P%c %d %d",subformat,pb->imageSize.h,pb->imageSize.v); if( !(e = bufputbytes(F,n,s)) ){ m = (1L << pb->depth)-1; n = sprintf(s," %ld",m); /* unless it's a bitmap, we need to write a third number in the header, denoting highest pixel value: 255 for 8 bit images, 65535 for 16 bit ones */ if( pb->depth == 1 || !(e = bufputbytes(F,n,s)) ){ bufputc(F,'\n'); pb->loPlane = 0; pb->hiPlane = pb->planes-1; pb->colBytes = pb->planes*pb->depth/8; pb->rowBytes = rb = ((long)pb->planes*pb->imageSize.h*pb->depth + 7)/8; pb->planeBytes = pb->depth/8; if( (outdata = malloc((long)chunk*rb)) ){ top = 0; nextchunk(pb); }else e = memFullErr; } } return e; } OSErr write_continue(FormatRecordPtr pb){ OSErr e = noErr; char *p; int i,j,mask; long count; if(top < pb->imageSize.v){ if(pb->depth == 1){ mask = ~(0xff >> (pb->imageSize.h & 7)); for(j = 0,p = pb->data ; j < chunk ; ++j,p += pb->rowBytes ){ // blank out rightmost (padding) bits of last image byte if(pb->imageSize.h & 7) p[pb->rowBytes-1] &= mask; if( (e = bufputbytes(F,pb->rowBytes,p)) ) break; } }else{ count = (long)pb->rowBytes*chunk; if( pb->depth == 16 ){ for( i = count/2, p = pb->data ; i-- ; ){ unsigned v = fix16( *(unsigned short*)p ); *p++ = v>>8; *p++ = v; } } e = bufputbytes(F,count,pb->data); } top += chunk; nextchunk(pb); }else pb->data = 0; // pb->theRect.left = pb->theRect.top = pb->theRect.right = pb->theRect.bottom = 0; return e; } OSErr write_finish(FormatRecordPtr pb){ free(outdata); flushbuffer(F); return noErr; }