int saveppm(char *filename, unsigned char *buf, int w, int h, enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup) { FILE *fs=NULL; int retcode=0; unsigned char *tempbuf=NULL; if((fs=fopen(filename, "wb"))==NULL) _throw(strerror(errno)); if(fprintf(fs, "P6\n")<1) _throw("Write error"); if(fprintf(fs, "%d %d\n", w, h)<1) _throw("Write error"); if(fprintf(fs, "255\n")<1) _throw("Write error"); if((tempbuf=(unsigned char *)malloc(w*h*3))==NULL) _throw("Memory allocation error"); pixelconvert(buf, f, srcpitch, tempbuf, BMP_RGB, w*3, w, h, srcbottomup); if((fwrite(tempbuf, w*h*3, 1, fs))!=1) _throw("Write error"); finally: if(tempbuf) free(tempbuf); if(fs) fclose(fs); return retcode; }
int loadppm(int *fd, unsigned char **buf, int *w, int *h, enum BMPPIXELFORMAT f, int align, int dstbottomup, int ascii) { FILE *fs=NULL; int retcode=0, scalefactor, dstpitch; unsigned char *tempbuf=NULL; char temps[255], temps2[255]; int numread=0, totalread=0, pixel[3], i, j; if((fs=fdopen(*fd, "r"))==NULL) _throw(strerror(errno)); do { if(!fgets(temps, 255, fs)) _throw("Read error"); if(strlen(temps)==0 || temps[0]=='\n') continue; if(sscanf(temps, "%s", temps2)==1 && temps2[1]=='#') continue; switch(totalread) { case 0: if((numread=sscanf(temps, "%d %d %d", w, h, &scalefactor))==EOF) _throw("Read error"); break; case 1: if((numread=sscanf(temps, "%d %d", h, &scalefactor))==EOF) _throw("Read error"); break; case 2: if((numread=sscanf(temps, "%d", &scalefactor))==EOF) _throw("Read error"); break; } totalread+=numread; } while(totalread<3); if((*w)<1 || (*h)<1 || scalefactor<1) _throw("Corrupt PPM header"); dstpitch=(((*w)*ps[f])+(align-1))&(~(align-1)); if((*buf=(unsigned char *)malloc(dstpitch*(*h)))==NULL) _throw("Memory allocation error"); if(ascii) { for(j=0; j<*h; j++) { for(i=0; i<*w; i++) { if(fscanf(fs, "%d%d%d", &pixel[0], &pixel[1], &pixel[2])!=3) _throw("Read error"); (*buf)[j*dstpitch+i*ps[f]+roffset[f]]=(unsigned char)(pixel[0]*255/scalefactor); (*buf)[j*dstpitch+i*ps[f]+goffset[f]]=(unsigned char)(pixel[1]*255/scalefactor); (*buf)[j*dstpitch+i*ps[f]+boffset[f]]=(unsigned char)(pixel[2]*255/scalefactor); } } } else { if(scalefactor!=255) _throw("Binary PPMs must have 8-bit components"); if((tempbuf=(unsigned char *)malloc((*w)*(*h)*3))==NULL) _throw("Memory allocation error"); if(fread(tempbuf, (*w)*(*h)*3, 1, fs)!=1) _throw("Read error"); pixelconvert(tempbuf, BMP_RGB, (*w)*3, *buf, f, dstpitch, *w, *h, dstbottomup); } finally: if(fs) {fclose(fs); *fd=-1;} if(tempbuf) free(tempbuf); return retcode; }
int savebmp(char *filename, unsigned char *buf, int w, int h, enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup) { int fd=-1, byteswritten, dstpitch, retcode=0; int flags=O_RDWR|O_CREAT|O_TRUNC; unsigned char *tempbuf=NULL; char *temp; bmphdr bh; int mode; #ifdef _WIN32 flags|=O_BINARY; mode=_S_IREAD|_S_IWRITE; #else mode=S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; #endif if(!filename || !buf || w<1 || h<1 || f<0 || f>BMPPIXELFORMATS-1 || srcpitch<0) _throw("bad argument to savebmp()"); if(srcpitch==0) srcpitch=w*ps[f]; if((temp=strrchr(filename, '.'))!=NULL) { if(!stricmp(temp, ".ppm")) return saveppm(filename, buf, w, h, f, srcpitch, srcbottomup); } _unix(fd=open(filename, flags, mode)); dstpitch=((w*3)+3)&(~3); bh.bfType=0x4d42; bh.bfSize=BMPHDRSIZE+dstpitch*h; bh.bfReserved1=0; bh.bfReserved2=0; bh.bfOffBits=BMPHDRSIZE; bh.biSize=40; bh.biWidth=w; bh.biHeight=h; bh.biPlanes=0; bh.biBitCount=24; bh.biCompression=BI_RGB; bh.biSizeImage=0; bh.biXPelsPerMeter=0; bh.biYPelsPerMeter=0; bh.biClrUsed=0; bh.biClrImportant=0; if(!littleendian()) { bh.bfType=byteswap16(bh.bfType); bh.bfSize=byteswap(bh.bfSize); bh.bfOffBits=byteswap(bh.bfOffBits); bh.biSize=byteswap(bh.biSize); bh.biWidth=byteswap(bh.biWidth); bh.biHeight=byteswap(bh.biHeight); bh.biPlanes=byteswap16(bh.biPlanes); bh.biBitCount=byteswap16(bh.biBitCount); bh.biCompression=byteswap(bh.biCompression); bh.biSizeImage=byteswap(bh.biSizeImage); bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter); bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter); bh.biClrUsed=byteswap(bh.biClrUsed); bh.biClrImportant=byteswap(bh.biClrImportant); } writeme(fd, &bh.bfType, sizeof(unsigned short)); writeme(fd, &bh.bfSize, sizeof(unsigned int)); writeme(fd, &bh.bfReserved1, sizeof(unsigned short)); writeme(fd, &bh.bfReserved2, sizeof(unsigned short)); writeme(fd, &bh.bfOffBits, sizeof(unsigned int)); writeme(fd, &bh.biSize, sizeof(unsigned int)); writeme(fd, &bh.biWidth, sizeof(int)); writeme(fd, &bh.biHeight, sizeof(int)); writeme(fd, &bh.biPlanes, sizeof(unsigned short)); writeme(fd, &bh.biBitCount, sizeof(unsigned short)); writeme(fd, &bh.biCompression, sizeof(unsigned int)); writeme(fd, &bh.biSizeImage, sizeof(unsigned int)); writeme(fd, &bh.biXPelsPerMeter, sizeof(int)); writeme(fd, &bh.biYPelsPerMeter, sizeof(int)); writeme(fd, &bh.biClrUsed, sizeof(unsigned int)); writeme(fd, &bh.biClrImportant, sizeof(unsigned int)); if((tempbuf=(unsigned char *)malloc(dstpitch*h))==NULL) _throw("Memory allocation error"); pixelconvert(buf, f, srcpitch, tempbuf, BMP_BGR, dstpitch, w, h, !srcbottomup); if((byteswritten=write(fd, tempbuf, dstpitch*h))!=dstpitch*h) _throw(strerror(errno)); finally: if(tempbuf) free(tempbuf); if(fd!=-1) close(fd); return retcode; }
int loadbmp(char *filename, unsigned char **buf, int *w, int *h, enum BMPPIXELFORMAT f, int align, int dstbottomup) { int fd=-1, bytesread, srcpitch, srcbottomup=1, srcps, dstpitch, retcode=0; unsigned char *tempbuf=NULL; bmphdr bh; int flags=O_RDONLY; dstbottomup=dstbottomup? 1:0; #ifdef _WIN32 flags|=O_BINARY; #endif if(!filename || !buf || !w || !h || f<0 || f>BMPPIXELFORMATS-1 || align<1) _throw("invalid argument to loadbmp()"); if((align&(align-1))!=0) _throw("Alignment must be a power of 2"); _unix(fd=open(filename, flags)); readme(fd, &bh.bfType, sizeof(unsigned short)); if(!littleendian()) bh.bfType=byteswap16(bh.bfType); if(bh.bfType==0x3650) { _catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 0)); goto finally; } if(bh.bfType==0x3350) { _catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 1)); goto finally; } readme(fd, &bh.bfSize, sizeof(unsigned int)); readme(fd, &bh.bfReserved1, sizeof(unsigned short)); readme(fd, &bh.bfReserved2, sizeof(unsigned short)); readme(fd, &bh.bfOffBits, sizeof(unsigned int)); readme(fd, &bh.biSize, sizeof(unsigned int)); readme(fd, &bh.biWidth, sizeof(int)); readme(fd, &bh.biHeight, sizeof(int)); readme(fd, &bh.biPlanes, sizeof(unsigned short)); readme(fd, &bh.biBitCount, sizeof(unsigned short)); readme(fd, &bh.biCompression, sizeof(unsigned int)); readme(fd, &bh.biSizeImage, sizeof(unsigned int)); readme(fd, &bh.biXPelsPerMeter, sizeof(int)); readme(fd, &bh.biYPelsPerMeter, sizeof(int)); readme(fd, &bh.biClrUsed, sizeof(unsigned int)); readme(fd, &bh.biClrImportant, sizeof(unsigned int)); if(!littleendian()) { bh.bfSize=byteswap(bh.bfSize); bh.bfOffBits=byteswap(bh.bfOffBits); bh.biSize=byteswap(bh.biSize); bh.biWidth=byteswap(bh.biWidth); bh.biHeight=byteswap(bh.biHeight); bh.biPlanes=byteswap16(bh.biPlanes); bh.biBitCount=byteswap16(bh.biBitCount); bh.biCompression=byteswap(bh.biCompression); bh.biSizeImage=byteswap(bh.biSizeImage); bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter); bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter); bh.biClrUsed=byteswap(bh.biClrUsed); bh.biClrImportant=byteswap(bh.biClrImportant); } if(bh.bfType!=0x4d42 || bh.bfOffBits<BMPHDRSIZE || bh.biWidth<1 || bh.biHeight==0) _throw("Corrupt bitmap header"); if((bh.biBitCount!=24 && bh.biBitCount!=32) || bh.biCompression!=BI_RGB) _throw("Only uncompessed RGB bitmaps are supported"); *w=bh.biWidth; *h=bh.biHeight; srcps=bh.biBitCount/8; if(*h<0) {*h=-(*h); srcbottomup=0;} srcpitch=(((*w)*srcps)+3)&(~3); dstpitch=(((*w)*ps[f])+(align-1))&(~(align-1)); if(srcpitch*(*h)+bh.bfOffBits!=bh.bfSize) _throw("Corrupt bitmap header"); if((tempbuf=(unsigned char *)malloc(srcpitch*(*h)))==NULL || (*buf=(unsigned char *)malloc(dstpitch*(*h)))==NULL) _throw("Memory allocation error"); if(lseek(fd, (long)bh.bfOffBits, SEEK_SET)!=(long)bh.bfOffBits) _throw(strerror(errno)); _unix(bytesread=read(fd, tempbuf, srcpitch*(*h))); if(bytesread!=srcpitch*(*h)) _throw("Read error"); pixelconvert(tempbuf, BMP_BGR, srcpitch, *buf, f, dstpitch, *w, *h, srcbottomup!=dstbottomup); finally: if(tempbuf) free(tempbuf); if(fd!=-1) close(fd); return retcode; }
int savebmp(char *filename, unsigned char *buf, int w, int h, int srcpf, int bottomup) { int retval=0, srcps, dstpf; struct jpeg_decompress_struct dinfo; struct my_error_mgr jerr; djpeg_dest_ptr dst; FILE *file=NULL; char *ptr=NULL; if(!filename || !buf || w<1 || h<1 || srcpf<0 || srcpf>=TJ_NUMPF) _throw("savebmp(): Invalid argument"); if((file=fopen(filename, "wb"))==NULL) _throwunix("savebmp(): Cannot open output file"); dinfo.err=jpeg_std_error(&jerr.pub); jerr.pub.error_exit=my_error_exit; jerr.pub.output_message=my_output_message; if(setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ retval=-1; goto bailout; } jpeg_create_decompress(&dinfo); if(srcpf==TJPF_GRAY) { dinfo.out_color_components=dinfo.output_components=1; dinfo.out_color_space=JCS_GRAYSCALE; } else { dinfo.out_color_components=dinfo.output_components=3; dinfo.out_color_space=JCS_RGB; } dinfo.image_width=w; dinfo.image_height=h; dinfo.global_state=DSTATE_READY; dinfo.scale_num=dinfo.scale_denom=1; ptr=strrchr(filename, '.'); if(ptr && !strcasecmp(ptr, ".bmp")) { if((dst=jinit_write_bmp(&dinfo, 0))==NULL) _throw("savebmp(): Could not initialize bitmap writer"); } else { if((dst=jinit_write_ppm(&dinfo))==NULL) _throw("savebmp(): Could not initialize PPM writer"); } dst->output_file=file; (*dst->start_output)(&dinfo, dst); (*dinfo.mem->realize_virt_arrays)((j_common_ptr)&dinfo); if(srcpf==TJPF_GRAY) dstpf=srcpf; else dstpf=TJPF_RGB; srcps=tjPixelSize[srcpf]; while(dinfo.output_scanline<dinfo.output_height) { int i, nlines=dst->buffer_height; for(i=0; i<nlines; i++) { unsigned char *inbuf; int row; row=dinfo.output_scanline+i; if(bottomup) inbuf=&buf[(h-row-1)*w*srcps]; else inbuf=&buf[row*w*srcps]; pixelconvert(inbuf, srcpf, bottomup, dst->buffer[i], dstpf, 0, w, nlines); } (*dst->put_pixel_rows)(&dinfo, dst, nlines); dinfo.output_scanline+=nlines; } (*dst->finish_output)(&dinfo, dst); bailout: jpeg_destroy_decompress(&dinfo); if(file) fclose(file); return retval; }
int loadbmp(char *filename, unsigned char **buf, int *w, int *h, int dstpf, int bottomup) { int retval=0, dstps, srcpf, tempc; struct jpeg_compress_struct cinfo; struct my_error_mgr jerr; cjpeg_source_ptr src; FILE *file=NULL; if(!filename || !buf || !w || !h || dstpf<0 || dstpf>=TJ_NUMPF) _throw("loadbmp(): Invalid argument"); if((file=fopen(filename, "rb"))==NULL) _throwunix("loadbmp(): Cannot open input file"); cinfo.err=jpeg_std_error(&jerr.pub); jerr.pub.error_exit=my_error_exit; jerr.pub.output_message=my_output_message; if(setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ retval=-1; goto bailout; } jpeg_create_compress(&cinfo); if((tempc=getc(file))<0 || ungetc(tempc, file)==EOF) _throwunix("loadbmp(): Could not read input file") else if(tempc==EOF) _throw("loadbmp(): Input file contains no data"); if(tempc=='B') { if((src=jinit_read_bmp(&cinfo))==NULL) _throw("loadbmp(): Could not initialize bitmap loader"); } else if(tempc=='P') { if((src=jinit_read_ppm(&cinfo))==NULL) _throw("loadbmp(): Could not initialize bitmap loader"); } else _throw("loadbmp(): Unsupported file type"); src->input_file=file; (*src->start_input)(&cinfo, src); (*cinfo.mem->realize_virt_arrays)((j_common_ptr)&cinfo); *w=cinfo.image_width; *h=cinfo.image_height; if(cinfo.input_components==1 && cinfo.in_color_space==JCS_RGB) srcpf=TJPF_GRAY; else srcpf=TJPF_RGB; dstps=tjPixelSize[dstpf]; if((*buf=(unsigned char *)malloc((*w)*(*h)*dstps))==NULL) _throw("loadbmp(): Memory allocation failure"); while(cinfo.next_scanline<cinfo.image_height) { int i, nlines=(*src->get_pixel_rows)(&cinfo, src); for(i=0; i<nlines; i++) { unsigned char *outbuf; int row; row=cinfo.next_scanline+i; if(bottomup) outbuf=&(*buf)[((*h)-row-1)*(*w)*dstps]; else outbuf=&(*buf)[row*(*w)*dstps]; pixelconvert(src->buffer[i], srcpf, 0, outbuf, dstpf, bottomup, *w, nlines); } cinfo.next_scanline+=nlines; } (*src->finish_input)(&cinfo, src); bailout: jpeg_destroy_compress(&cinfo); if(file) fclose(file); if(retval<0 && buf && *buf) {free(*buf); *buf=NULL;} return retval; }