X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/02d1d62827cef86398edc2013f7d2ff04bf21c63..a3b721bb9af3baf668992e08d966b0f768d61e44:/raw.c diff --git a/raw.c b/raw.c index 56977e79..bae403d0 100644 --- a/raw.c +++ b/raw.c @@ -1,14 +1,13 @@ -#include "image.h" +#include "imager.h" #include +#include "iolayer.h" #ifndef _MSC_VER #include #endif #include +#include -#define TRUE 1 -#define FALSE 0 -#define BSIZ 100*BUFSIZ /* @@ -24,75 +23,172 @@ intrl: interlace flag, 0 = sample interleaving 1 = line interleaving - 2 = image interleaving + 2 = image interleaving (not implemented) */ +static void -expandchannels(unsigned char *inbuffer,unsigned char *outbuffer,int chunks,int datachannels,int storechannels) { - int ch,i; - if (inbuffer==outbuffer) return; /* Check if data is already in expanded format */ - for(ch=0;ch datachannels ? datachannels : storechannels; + if (inbuffer == outbuffer) + return; /* Check if data is already in expanded format */ + for(x = 0; x < xsize; x++) { + for (ch = 0; ch < copy_chans; ch++) + outbuffer[x*storechannels+ch] = inbuffer[x*datachannels+ch]; + for (; ch < storechannels; ch++) + outbuffer[x*storechannels+ch] = 0; + } } i_img * -i_readraw(int fd,int x,int y,int datachannels,int storechannels,int intrl) { +i_readraw_wiol(io_glue *ig, i_img_dim x, i_img_dim y, int datachannels, int storechannels, int intrl) { i_img* im; - int rc,k; - + ssize_t rc; + i_img_dim k; + unsigned char *inbuffer; unsigned char *ilbuffer; unsigned char *exbuffer; - int inbuflen,ilbuflen,exbuflen; + size_t inbuflen,ilbuflen,exbuflen; - mm_log((1,"readraw(fd %d,x %d,y %d,datachannels %d,storechannels %d,intrl %d)\n",fd,x,y,datachannels,storechannels,intrl)); - - im=i_img_empty_ch(NULL,x,y,storechannels); + i_clear_error(); - inbuflen=im->xsize*datachannels; - ilbuflen=inbuflen; - exbuflen=im->xsize*storechannels; - inbuffer=(unsigned char*)mymalloc(inbuflen); - mm_log((1,"inbuflen: %d, ilbuflen: %d, exbuflen: %d.\n",inbuflen,ilbuflen,exbuflen)); - - if (intrl==0) ilbuffer=inbuffer; else ilbuffer=(unsigned char*)mymalloc(inbuflen); - if (datachannels==storechannels) exbuffer=ilbuffer; else exbuffer=(unsigned char*)mymalloc(exbuflen); + mm_log((1, "i_readraw(ig %p,x %" i_DF ",y %" i_DF ",datachannels %d,storechannels %d,intrl %d)\n", + ig, i_DFc(x), i_DFc(y), datachannels, storechannels, intrl)); + if (intrl != 0 && intrl != 1) { + i_push_error(0, "raw_interleave must be 0 or 1"); + return NULL; + } + if (storechannels < 1 || storechannels > 4) { + i_push_error(0, "raw_storechannels must be between 1 and 4"); + return NULL; + } + + im = i_img_empty_ch(NULL,x,y,storechannels); + if (!im) + return NULL; + + inbuflen = im->xsize*datachannels; + ilbuflen = inbuflen; + exbuflen = im->xsize*storechannels; + inbuffer = (unsigned char*)mymalloc(inbuflen); + mm_log((1,"inbuflen: %ld, ilbuflen: %ld, exbuflen: %ld.\n", + (long)inbuflen, (long)ilbuflen, (long)exbuflen)); + + if (intrl==0) ilbuffer = inbuffer; + else ilbuffer=mymalloc(inbuflen); + + if (datachannels==storechannels) exbuffer=ilbuffer; + else exbuffer= mymalloc(exbuflen); + k=0; - while(kysize) { - rc=myread(fd,inbuffer,inbuflen); - if (rc!=inbuflen) { fprintf(stderr,"Premature end of file.\n"); exit(2); } + while( kysize ) { + rc = i_io_read(ig, inbuffer, inbuflen); + if (rc != inbuflen) { + if (rc < 0) + i_push_error(0, "error reading file"); + else + i_push_error(0, "premature end of file"); + i_img_destroy(im); + myfree(inbuffer); + if (intrl != 0) myfree(ilbuffer); + if (datachannels != storechannels) myfree(exbuffer); + return NULL; + } interleave(inbuffer,ilbuffer,im->xsize,datachannels); expandchannels(ilbuffer,exbuffer,im->xsize,datachannels,storechannels); - memcpy(&(im->data[im->xsize*storechannels*k]),exbuffer,exbuflen); + /* FIXME: Do we ever want to save to a virtual image? */ + memcpy(&(im->idata[im->xsize*storechannels*k]),exbuffer,exbuflen); k++; } myfree(inbuffer); - if (intrl!=0) myfree(ilbuffer); - if (datachannels!=storechannels) myfree(exbuffer); + if (intrl != 0) myfree(ilbuffer); + if (datachannels != storechannels) myfree(exbuffer); + + i_tags_add(&im->tags, "i_format", 0, "raw", -1, 0); + return im; } undef_int -i_writeraw(i_img* im,int fd) { - int rc; - mm_log((1,"writeraw(im 0x%x,fd %d)\n",im,fd)); +i_writeraw_wiol(i_img* im, io_glue *ig) { + ssize_t rc; + + i_clear_error(); + mm_log((1,"writeraw(im %p,ig %p)\n", im, ig)); if (im == NULL) { mm_log((1,"Image is empty\n")); return(0); } - rc=mywrite(fd,im->data,im->bytes); - if (rc!=im->bytes) { mm_log((1,"i_writeraw: Couldn't write to file\n")); return(0); } - return(1); -} - - - - - - - + if (!im->virtual) { + rc = i_io_write(ig,im->idata,im->bytes); + if (rc != im->bytes) { + i_push_error(errno, "Could not write to file"); + mm_log((1,"i_writeraw: Couldn't write to file\n")); + return(0); + } + } else { + if (im->type == i_direct_type) { + /* just save it as 8-bits, maybe support saving higher bit count + raw images later */ + size_t line_size = im->xsize * im->channels; + unsigned char *data = mymalloc(line_size); + + i_img_dim y = 0; + rc = line_size; + while (rc == line_size && y < im->ysize) { + i_gsamp(im, 0, im->xsize, y, data, NULL, im->channels); + rc = i_io_write(ig, data, line_size); + ++y; + } + if (rc != line_size) { + i_push_error(errno, "write error"); + return 0; + } + myfree(data); + } else { + /* paletted image - assumes the caller puts the palette somewhere + else + */ + size_t line_size = sizeof(i_palidx) * im->xsize; + i_palidx *data = mymalloc(sizeof(i_palidx) * im->xsize); + + i_img_dim y = 0; + rc = line_size; + while (rc == line_size && y < im->ysize) { + i_gpal(im, 0, im->xsize, y, data); + rc = i_io_write(ig, data, line_size); + ++y; + } + myfree(data); + if (rc != line_size) { + i_push_error(errno, "write error"); + return 0; + } + } + } + if (i_io_close(ig)) + return 0; + return(1); +}