static GifFileType * DGifOpen(void *userData, InputFunc readFunc) { unsigned char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; GifFile = (GifFileType *) gif_malloc(sizeof(GifFileType)); if (GifFile == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); Private = (GifFilePrivateType *) gif_malloc(sizeof(GifFilePrivateType)); if (!Private) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; gif_free((char *) GifFile); return NULL; } GifFile->Private = (VoidPtr) Private; Private->FileHandle = 0; Private->File = 0; Private->FileState = FILE_STATE_READ; Private->Read = readFunc; /* TVT */ GifFile->UserData = userData; /* TVT */ if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { _GifError = D_GIF_ERR_READ_FAILED; gif_free((char *) Private); gif_free((char *) GifFile); return NULL; } Buf[GIF_STAMP_LEN] = 0; if (strncmp(GIF_STAMP, (void *) Buf, GIF_VERSION_POS) != 0) { _GifError = D_GIF_ERR_NOT_GIF_FILE; gif_free((char *) Private); gif_free((char *) GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { gif_free((char *) Private); gif_free((char *) GifFile); return NULL; } _GifError = 0; return GifFile; }
/****************************************************************************** * Update a new gif file, given its file handle. * * Returns GifFileType pointer dynamically allocated which serves as the gif * * info record. _GifError is cleared if succesfull. * ******************************************************************************/ GifFileType *DGifOpenFileMemory(const u8* input, u32 input_len) { GifFileType *GifFile; GifFilePrivateType *Private; if ((GifFile = (GifFileType *) malloc(sizeof(GifFileType))) == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); if ((Private = (GifFilePrivateType *) malloc(sizeof(GifFilePrivateType))) == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; free((char *) GifFile); return NULL; } GifFile->Private = (VoidPtr) Private; Private->input = input + GIF_STAMP_LEN; Private->input_len = input_len - GIF_STAMP_LEN; Private->FileState = 0; /* Make sure bit 0 = 0 (File open for read). */ if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { free((char *) Private); free((char *) GifFile); return NULL; } _GifError = 0; return GifFile; }
/****************************************************************************** * GifFileType constructor with user supplied input function (TVT) *****************************************************************************/ GifFileType * DGifOpen(void *userData, InputFunc readFunc) { unsigned char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (!Private) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; free((char *)GifFile); return NULL; } GifFile->Private = (VoidPtr)Private; Private->FileHandle = 0; Private->File = 0; Private->FileState = FILE_STATE_READ; Private->Read = readFunc; /* TVT */ GifFile->UserData = userData; /* TVT */ /* Lets see if this is a GIF file: */ if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { _GifError = D_GIF_ERR_READ_FAILED; free((char *)Private); free((char *)GifFile); return NULL; } /* The GIF Version number is ignored at this time. Maybe we should do * something more useful with it. */ Buf[GIF_STAMP_LEN] = 0; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { _GifError = D_GIF_ERR_NOT_GIF_FILE; free((char *)Private); free((char *)GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { free((char *)Private); free((char *)GifFile); return NULL; } _GifError = 0; return GifFile; }
/****************************************************************************** * GifFileType constructor with user supplied input function (TVT) *****************************************************************************/ GifFileType * DGifOpen(void *userData, InputFunc readFunc) { unsigned char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; GifFile = ungif_alloc(sizeof(GifFileType)); if (GifFile == NULL) { return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); Private = ungif_alloc(sizeof(GifFilePrivateType)); if (!Private) { ungif_free(GifFile); return NULL; } GifFile->Private = (void*)Private; Private->Read = readFunc; /* TVT */ GifFile->UserData = userData; /* TVT */ /* Lets see if this is a GIF file: */ if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { ungif_free(Private); ungif_free(GifFile); return NULL; } /* The GIF Version number is ignored at this time. Maybe we should do * something more useful with it. */ Buf[GIF_STAMP_LEN] = 0; if (memcmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { ungif_free(Private); ungif_free(GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { ungif_free(Private); ungif_free(GifFile); return NULL; } return GifFile; }
/****************************************************************************** Update a new GIF file, given its file handle. Returns dynamically allocated GifFileType pointer which serves as the GIF info record. ******************************************************************************/ GifFileType * DGifOpenFileHandle(int FileHandle, int *Error) { char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; FILE *f; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { if (Error != NULL) *Error = D_GIF_ERR_NOT_ENOUGH_MEM; (void)close(FileHandle); return NULL; } /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType)); /* Belt and suspenders, in case the null pointer isn't zero */ GifFile->SavedImages = NULL; GifFile->SColorMap = NULL; Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (Private == NULL) { if (Error != NULL) *Error = D_GIF_ERR_NOT_ENOUGH_MEM; (void)close(FileHandle); free((char *)GifFile); return NULL; } #ifdef _WIN32 _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ #endif /* _WIN32 */ f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ /*@-mustfreeonly@*/ GifFile->Private = (void *)Private; Private->FileHandle = FileHandle; Private->File = f; Private->FileState = FILE_STATE_READ; Private->Read = NULL; /* don't use alternate input method (TVT) */ GifFile->UserData = NULL; /* TVT */ /*@=mustfreeonly@*/ /* Let's see if this is a GIF file: */ if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { if (Error != NULL) *Error = D_GIF_ERR_READ_FAILED; (void)fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } /* Check for GIF prefix at start of file */ Buf[GIF_STAMP_LEN] = 0; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { if (Error != NULL) *Error = D_GIF_ERR_NOT_GIF_FILE; (void)fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { (void)fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } GifFile->Error = 0; /* What version of GIF? */ Private->gif89 = (Buf[GIF_VERSION_POS] == '9'); return GifFile; }
/****************************************************************************** GifFileType constructor with user supplied input function (TVT) ******************************************************************************/ GifFileType * DGifOpen(void *userData, InputFunc readFunc, int *Error) { char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { if (Error != NULL) *Error = D_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); /* Belt and suspenders, in case the null pointer isn't zero */ GifFile->SavedImages = NULL; GifFile->SColorMap = NULL; Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (!Private) { if (Error != NULL) *Error = D_GIF_ERR_NOT_ENOUGH_MEM; free((char *)GifFile); return NULL; } GifFile->Private = (void *)Private; Private->FileHandle = 0; Private->File = NULL; Private->FileState = FILE_STATE_READ; Private->Read = readFunc; /* TVT */ GifFile->UserData = userData; /* TVT */ /* Lets see if this is a GIF file: */ if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { if (Error != NULL) *Error = D_GIF_ERR_READ_FAILED; free((char *)Private); free((char *)GifFile); return NULL; } /* Check for GIF prefix at start of file */ Buf[GIF_STAMP_LEN] = '\0'; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { if (Error != NULL) *Error = D_GIF_ERR_NOT_GIF_FILE; free((char *)Private); free((char *)GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { free((char *)Private); free((char *)GifFile); return NULL; } GifFile->Error = 0; /* What version of GIF? */ Private->gif89 = (Buf[GIF_VERSION_POS] == '9'); return GifFile; }
int main(int argc, char **argv) { // // local vars // GifFileType *GIFfile; GifRecordType GIFtype; GifByteType *GIFextension; GifPixelType *GIFline; uint32_t w[8],**lower_array,**upper_array; int x,y,z,i,j,k,n,p,imin,imax; int image_width,image_height,image_count,color_resolution,GIFcode,ret; float threshold,voxel_size; char comment[256],rules[255][20]; struct fab_vars v; init_vars(&v); // // command line args // if (!((argc == 3) || (argc == 4) || (argc == 5) || (argc == 6))) { printf("command line: gif_stl in.gif out.stl [threshold [size [points [angle]]]]\n"); printf(" in.gif = input GIF section file\n"); printf(" out.stl = output STL file\n"); printf(" threshold: surface intensity threshold (0 = min, 1 = max, default 0.5))\n"); printf(" size = voxel size (mm, default from file))\n"); printf(" points = points to interpolate per point (default 0)\n"); printf(" to be implemented: angle = minimum relative face angle to decimate vertices (default 0)\n"); exit(-1); } p = 0; threshold = 0.5; voxel_size = -1; image_width = -1; image_height = -1; image_count = -1; if (argc >= 4) sscanf(argv[3],"%f",&threshold); if (argc >= 5) sscanf(argv[4],"%f",&voxel_size); if (argc >= 6) sscanf(argv[5],"%d",&p); // // initialize the rule table // init_rules(rules); // // scan the file // printf("read %s\n",argv[1]); color_resolution = -1; #if GIFLIB_MAJOR >= 5 GIFfile = DGifOpenFileName(argv[1], NULL); #else GIFfile = DGifOpenFileName(argv[1]); #endif if (GIFfile == NULL) { printf("gif_stl: oops -- can not open %s\n",argv[1]); exit(-1); } GIFline = malloc(MAX_LINE*sizeof(GifPixelType)); imin = 256; imax = 0; do { DGifGetRecordType(GIFfile,&GIFtype); switch (GIFtype) { case IMAGE_DESC_RECORD_TYPE: DGifGetImageDesc(GIFfile); image_width = GIFfile->SWidth; image_height = GIFfile->SHeight; image_count = GIFfile->ImageCount; color_resolution = GIFfile->SColorResolution; for (y = 0; y < GIFfile->SHeight; ++y) { ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth); if (ret != GIF_OK) { printf("gif_stl: oops -- error reading line\n"); exit(-1); } for (x = 0; x < GIFfile->SWidth; ++x) { if (GIFline[x] < imin) imin = GIFline[x]; if (GIFline[x] > imax) imax = GIFline[x]; } } break; case EXTENSION_RECORD_TYPE: DGifGetExtension(GIFfile,&GIFcode,&GIFextension); if (GIFcode == COMMENT_EXT_FUNC_CODE) { n = GIFextension[0]; for (i = 1; i <= n; ++i) comment[i-1] = GIFextension[i]; comment[n] = 0; if (voxel_size == -1) sscanf(comment,"mm per pixel: %f;",&voxel_size); } while (GIFextension != NULL) DGifGetExtensionNext(GIFfile,&GIFextension); break; case SCREEN_DESC_RECORD_TYPE: DGifGetScreenDesc(GIFfile); break; case TERMINATE_RECORD_TYPE: break; case UNDEFINED_RECORD_TYPE: printf("gif_stl: oops -- undefined GIF record type\n"); exit(-1); break; } } while (GIFtype != TERMINATE_RECORD_TYPE); if (GIFfile == NULL) { printf("gif_stl: oops -- can not open %s\n",argv[1]); exit(-1); } if (voxel_size == -1) { voxel_size = 1.0; printf(" no pixel size found, assuming 1 mm\n"); } printf(" voxel size (mm): %f, color resolution (bits): %d\n",voxel_size,color_resolution); printf(" intensity min: %d max: %d\n",imin,imax); printf(" number of images: %d, image width %d, image height %d\n",image_count,image_width,image_height); // // set threshold // threshold = imin + threshold*(imax-imin); // // add empty border // image_width += 2; image_height += 2; image_count += 2; // // allocate arrays // lower_array = malloc(image_height*sizeof(uint32_t *)); for (y = 0; y < image_height; ++y) { lower_array[y] = malloc(image_width*sizeof(uint32_t)); for (x = 0; x < image_width; ++x) lower_array[y][x] = 0; } upper_array = malloc(image_height*sizeof(uint32_t *)); for (y = 0; y < image_height; ++y) { upper_array[y] = malloc(image_width*sizeof(uint32_t)); for (x = 0; x < image_width; ++x) upper_array[y][x] = 0; } // // read the file // DGifCloseFile(GIFfile); #if GIFLIB_MAJOR >= 5 GIFfile = DGifOpenFileName(argv[1], NULL); #else GIFfile = DGifOpenFileName(argv[1]); #endif if (GIFfile == NULL) { printf("gif_stl: oops -- can not open %s\n",argv[1]); exit(-1); } z = 0; v.mesh = malloc(sizeof(struct fab_mesh_type)); v.mesh->triangle = malloc(sizeof(struct fab_mesh_triangle_type)); v.mesh->first = v.mesh->triangle; v.mesh->last = v.mesh->triangle; v.mesh->triangle->previous = v.mesh->triangle->next = 0; do { DGifGetRecordType(GIFfile,&GIFtype); switch (GIFtype) { case IMAGE_DESC_RECORD_TYPE: // // read image // DGifGetImageDesc(GIFfile); printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b layer = %d",z); // // read layer // for (y = 0; y < (image_height-2); ++y) { ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth); if (ret != GIF_OK) { printf("gif_stl: oops -- error reading line\n"); exit(-1); } for (x = 0; x < (image_width-2); ++x) { lower_array[y+1][x+1] = upper_array[y+1][x+1]; upper_array[y+1][x+1] = GIFline[x]; } } if (p == 0) { // // no interpolation, loop over layer voxels // for (x = 0; x < (image_width-1); ++x) { for (y = 0; y < (image_height-1); ++y) { w[0] = lower_array[y][x]; w[1] = lower_array[y][x+1]; w[2] = lower_array[y+1][x]; w[3] = lower_array[y+1][x+1]; w[4] = upper_array[y][x]; w[5] = upper_array[y][x+1]; w[6] = upper_array[y+1][x]; w[7] = upper_array[y+1][x+1]; triangulate(x,y,z,voxel_size,threshold,w,rules,&v); } } } else { // // yes interpolation, loop over layer sub-voxels // for (x = 0; x < (image_width-1); ++x) { for (y = 0; y < (image_height-1); ++y) { for (i = 0; i <= p; ++i) { for (j = 0; j <= p; ++j) { for (k = 0; k <= p; ++k) { w[0] = interp(x,y,i,j,k,lower_array,upper_array,p); w[1] = interp(x,y,i+1,j,k,lower_array,upper_array,p); w[2] = interp(x,y,i,j+1,k,lower_array,upper_array,p); w[3] = interp(x,y,i+1,j+1,k,lower_array,upper_array,p); w[4] = interp(x,y,i,j,k+1,lower_array,upper_array,p); w[5] = interp(x,y,i+1,j,k+1,lower_array,upper_array,p); w[6] = interp(x,y,i,j+1,k+1,lower_array,upper_array,p); w[7] = interp(x,y,i+1,j+1,k+1,lower_array,upper_array,p); triangulate((1+p)*x+i,(1+p)*y+j,(1+p)*z+k,voxel_size,threshold,w,rules,&v); } } } } } } z += 1; break; case EXTENSION_RECORD_TYPE: DGifGetExtension(GIFfile,&GIFcode,&GIFextension); while (GIFextension != NULL) DGifGetExtensionNext(GIFfile,&GIFextension); break; case SCREEN_DESC_RECORD_TYPE: DGifGetScreenDesc(GIFfile); break; case TERMINATE_RECORD_TYPE: break; case UNDEFINED_RECORD_TYPE: printf("gif_stl: oops -- undefined GIF record type\n"); exit(-1); break; } } while (GIFtype != TERMINATE_RECORD_TYPE); // // add empty top layer // printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b layer = %d",z); for (y = 0; y < (image_height-2); ++y) { for (x = 0; x < (image_width-2); ++x) { lower_array[y+1][x+1] = upper_array[y+1][x+1]; upper_array[y+1][x+1] = 0; } } if (p == 0) { // // no interpolation, loop over layer voxels // for (x = 0; x < (image_width-1); ++x) { for (y = 0; y < (image_height-1); ++y) { w[0] = lower_array[y][x]; w[1] = lower_array[y][x+1]; w[2] = lower_array[y+1][x]; w[3] = lower_array[y+1][x+1]; w[4] = upper_array[y][x]; w[5] = upper_array[y][x+1]; w[6] = upper_array[y+1][x]; w[7] = upper_array[y+1][x+1]; triangulate(x,y,z,voxel_size,threshold,w,rules,&v); } } } else { // // yes interpolation, loop over layer sub-voxels // for (x = 0; x < (image_width-1); ++x) { for (y = 0; y < (image_height-1); ++y) { for (i = 0; i <= p; ++i) { for (j = 0; j <= p; ++j) { for (k = 0; k <= p; ++k) { w[0] = interp(x,y,i,j,k,lower_array,upper_array,p); w[1] = interp(x,y,i+1,j,k,lower_array,upper_array,p); w[2] = interp(x,y,i,j+1,k,lower_array,upper_array,p); w[3] = interp(x,y,i+1,j+1,k,lower_array,upper_array,p); w[4] = interp(x,y,i,j,k+1,lower_array,upper_array,p); w[5] = interp(x,y,i+1,j,k+1,lower_array,upper_array,p); w[6] = interp(x,y,i,j+1,k+1,lower_array,upper_array,p); w[7] = interp(x,y,i+1,j+1,k+1,lower_array,upper_array,p); triangulate((1+p)*x+i,(1+p)*y+j,(1+p)*z+k,voxel_size,threshold,w,rules,&v); } } } } } } printf("\n"); // // write STL // fab_write_stl(&v,argv[2]); // // exit // DGifCloseFile(GIFfile); exit(0); }
/****************************************************************************** * Update a new gif file, given its file handle. * Returns GifFileType pointer dynamically allocated which serves as the gif * info record. _GifError is cleared if succesfull. *****************************************************************************/ GifFileType * DGifOpenFileHandle(int FileHandle) { unsigned char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; FILE *f; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; close(FileHandle); return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (Private == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; close(FileHandle); free((char *)GifFile); return NULL; } #if defined(__MSDOS__) || defined(WIN32) || defined(WIN64) || defined(_OPEN_BINARY) setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ #endif /* __MSDOS__ */ f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ #if defined(__MSDOS__) || defined(WIN32) || defined(WIN64) setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream buffer. */ #endif /* __MSDOS__ */ GifFile->Private = (VoidPtr)Private; Private->FileHandle = FileHandle; Private->File = f; Private->FileState = FILE_STATE_READ; Private->Read = 0; /* don't use alternate input method (TVT) */ GifFile->UserData = 0; /* TVT */ /* Lets see if this is a GIF file: */ if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { _GifError = D_GIF_ERR_READ_FAILED; fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } /* The GIF Version number is ignored at this time. Maybe we should do * something more useful with it. */ Buf[GIF_STAMP_LEN] = 0; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { _GifError = D_GIF_ERR_NOT_GIF_FILE; fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } _GifError = 0; return GifFile; }
int main(int argc, char **argv) { // // local vars // GifFileType *GIFfile; GifRecordType GIFtype; GifByteType *GIFextension; GifPixelType *GIFline; uint32_t **lower_array,**upper_array; double **image_array; double f,fmin,fmax; int x,y,z,h,i,j,k,n,p; int image_width,image_height,image_count,color_resolution,GIFcode,ret; float pixel_size,arg,rx,ry,rz; char type,comment[256]; struct fab_vars v; init_vars(&v); // // command line args // if (!((argc == 3) || (argc == 4) || (argc == 5) || (argc == 6) || (argc == 7) || (argc == 10))) { printf("command line: gif_png in.gif out.png [type [arg [points [size [rx ry rz]]]]]\n"); printf(" in.gif = input gif file\n"); printf(" out.png = output PNG file\n"); printf(" type = 'z' of density, 'h' for height (default z)\n"); printf(" arg = gamma for 'z', threshold for 'h' (default 1)\n"); printf(" points = points to interpolate per point (linear, default 0)\n"); printf(" size = voxel size (mm, default from file))\n"); printf(" to be implemented: rx,ry,rz = x,y,z rotation angles (degrees; default 0)\n"); exit(-1); } type = 'z'; p = 0; arg = 1; rx = ry = rz = 0; pixel_size = -1; image_width = -1; image_height = -1; if (argc >= 4) { sscanf(argv[3],"%c",&type); if (!((type == 'z') || (type == 'h'))) { printf("gif_png: oops -- type must be 'z' or 'h'\n"); exit(-1); } if (argc >= 5) sscanf(argv[4],"%f",&arg); } if (argc >= 6) sscanf(argv[5],"%d",&p); if (argc >= 7) sscanf(argv[6],"%f",&pixel_size); if (argc >= 10) { sscanf(argv[7],"%f",&rx); sscanf(argv[8],"%f",&ry); sscanf(argv[9],"%f",&rz); } // // scan the file // printf("read %s\n",argv[1]); color_resolution = -1; GIFfile = DGifOpenFileName(argv[1]); if (GIFfile == NULL) { printf("gif_png: oops -- can not open %s\n",argv[1]); exit(-1); } GIFline = malloc(MAX_LINE*sizeof(GifPixelType)); do { DGifGetRecordType(GIFfile,&GIFtype); switch (GIFtype) { case IMAGE_DESC_RECORD_TYPE: DGifGetImageDesc(GIFfile); image_width = GIFfile->SWidth; image_height = GIFfile->SHeight; image_count = GIFfile->ImageCount; color_resolution = GIFfile->SColorResolution; for (y = 0; y < GIFfile->SHeight; ++y) { ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth); if (ret != GIF_OK) { printf("gif_png: oops -- error reading line\n"); exit(-1); } } break; case EXTENSION_RECORD_TYPE: DGifGetExtension(GIFfile,&GIFcode,&GIFextension); if (GIFcode == COMMENT_EXT_FUNC_CODE) { n = GIFextension[0]; for (i = 1; i <= n; ++i) comment[i-1] = GIFextension[i]; comment[n] = 0; if (pixel_size == -1) sscanf(comment,"mm per pixel: %f;",&pixel_size); } while (GIFextension != NULL) DGifGetExtensionNext(GIFfile,&GIFextension); break; case SCREEN_DESC_RECORD_TYPE: DGifGetScreenDesc(GIFfile); break; case TERMINATE_RECORD_TYPE: break; case UNDEFINED_RECORD_TYPE: printf("gif_png: oops -- undefined GIF record type\n"); exit(-1); break; } } while (GIFtype != TERMINATE_RECORD_TYPE); if (GIFfile == NULL) { printf("gif_png: oops -- can not open %s\n",argv[1]); exit(-1); } if (pixel_size == -1) { pixel_size = 1.0; printf(" no pixel size found, assuming 1 mm\n"); } printf(" pixel size (mm): %f, color resolution (bits): %d\n",pixel_size,color_resolution); printf(" number of images: %d, image width %d, image height %d\n",image_count,image_width,image_height); // // check and set limits // v.nx = image_width + (image_width-1)*p; v.ny = image_height + (image_height-1)*p; v.nz = image_count + (image_count-1)*p; v.dx = v.nx*pixel_size; v.dy = v.ny*pixel_size; v.dz = v.nz*pixel_size; v.xmin = 0; v.ymin = 0; v.zmin = 0; // // allocate arrays // lower_array = malloc(image_height*sizeof(uint32_t *)); for (y = 0; y < image_height; ++y) { lower_array[y] = malloc(image_width*sizeof(uint32_t)); for (x = 0; x < image_width; ++x) lower_array[y][x] = 0; } upper_array = malloc(image_height*sizeof(uint32_t *)); for (y = 0; y < image_height; ++y) { upper_array[y] = malloc(image_width*sizeof(uint32_t)); for (x = 0; x < image_width; ++x) upper_array[y][x] = 0; } image_array = malloc(v.ny*sizeof(double *)); for (y = 0; y < v.ny; ++y) { image_array[y] = malloc(v.nx*sizeof(double)); for (x = 0; x < v.nx; ++x) image_array[y][x] = 0; } v.array = malloc(v.ny*sizeof(uint32_t *)); for (y = 0; y < v.ny; ++y) { v.array[y] = malloc(v.nx*sizeof(uint32_t)); for (x = 0; x < v.nx; ++x) v.array[y][x] = 0; } // // read the file // DGifCloseFile(GIFfile); GIFfile = DGifOpenFileName(argv[1]); if (GIFfile == NULL) { printf("gif_png: oops -- can not open %s\n",argv[1]); exit(-1); } z = 0; do { DGifGetRecordType(GIFfile,&GIFtype); switch (GIFtype) { case IMAGE_DESC_RECORD_TYPE: // // read image // DGifGetImageDesc(GIFfile); printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b layer = %d",z); if (z == 0) { // // read first layer // for (y = 0; y < image_height; ++y) { ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth); if (ret != GIF_OK) { printf("gif_png: oops -- error reading first line\n"); exit(-1); } for (x = 0; x < image_width; ++x) upper_array[y][x] = GIFline[x]; } } else { // // read next layer // for (y = 0; y < image_height; ++y) { ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth); if (ret != GIF_OK) { printf("gif_png: oops -- error reading line\n"); exit(-1); } for (x = 0; x < image_width; ++x) { lower_array[y][x] = upper_array[y][x]; upper_array[y][x] = GIFline[x]; } } // // interpolate layer image // for (x = 0; x < (image_width-1); ++x) { for (y = 0; y < (image_height-1); ++y) { for (i = 0; i <= p; ++i) { for (j = 0; j <= p; ++j) { for (k = 0; k <= p; ++k) { f = lower_array[y][x]*((p+1.0-i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((p+1.0-k)/(p+1.0)) + lower_array[y][x+1]*((i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((p+1.0-k)/(p+1.0)) + lower_array[y+1][x]*((p+1.0-i)/(p+1.0))*((j)/(p+1.0))*((p+1.0-k)/(p+1.0)) + lower_array[y+1][x+1]*((i)/(p+1.0))*((j)/(p+1.0))*((p+1.0-k)/(p+1.0)) + upper_array[y][x]*((p+1.0-i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((k)/(p+1.0)) + upper_array[y][x+1]*((i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((k)/(p+1.0)) + upper_array[y+1][x]*((p+1.0-i)/(p+1.0))*((j)/(p+1.0))*((k)/(p+1.0)) + upper_array[y+1][x+1]*((i)/(p+1.0))*((j)/(p+1.0))*((k)/(p+1.0)); if (type == 'z') { image_array[(1+p)*y+j][(1+p)*x+i] += f; } else if (type == 'h') { h = (1+p)*z+k; if ((f > arg) && (h > image_array[(1+p)*y+j][(1+p)*x+i])) image_array[(1+p)*y+j][(1+p)*x+i] = h; } } } } } } } z += 1; break; case EXTENSION_RECORD_TYPE: DGifGetExtension(GIFfile,&GIFcode,&GIFextension); while (GIFextension != NULL) DGifGetExtensionNext(GIFfile,&GIFextension); break; case SCREEN_DESC_RECORD_TYPE: DGifGetScreenDesc(GIFfile); break; case TERMINATE_RECORD_TYPE: break; case UNDEFINED_RECORD_TYPE: printf("gif_png: oops -- undefined GIF record type\n"); exit(-1); break; } } while (GIFtype != TERMINATE_RECORD_TYPE); printf("\n"); // // scale image and copy to PNG array // if (type == 'z') { fmin = BIG; fmax = 0; for (x = 0; x < v.nx; ++x) { for (y = 0; y < v.ny; ++y) { if (image_array[y][x] > fmax) fmax = image_array[y][x]; if (image_array[y][x] < fmin) fmin = image_array[y][x]; } } if (arg == 1) { for (x = 0; x < v.nx; ++x) for (y = 0; y < v.ny; ++y) v.array[y][x] = 65536*(image_array[y][x]-fmin)/(fmax-fmin); } else { for (x = 0; x < v.nx; ++x) for (y = 0; y < v.ny; ++y) v.array[y][x] = 65536*pow((image_array[y][x]-fmin)/(fmax-fmin),arg); } } else if (type == 'h') { for (x = 0; x < v.nx; ++x) for (y = 0; y < v.ny; ++y) v.array[y][x] = 65536*image_array[y][x]/(v.nz-1.0); } // // write PNG // v.bit_depth = 16; fab_write_png_K(&v,argv[2]); // // exit // DGifCloseFile(GIFfile); exit(0); }
/****************************************************************************** * Update a new gif file, given its file handle. * Returns GifFileType pointer dynamically allocated which serves as the gif * info record. _GifError is cleared if succesful. *****************************************************************************/ GifFileType * DGifOpenFileHandle(int FileHandle) { char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; FILE *f; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; (void)close(FileHandle); return NULL; } /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType)); /* Belt and suspenders, in case the null pointer isn't zero */ GifFile->SavedImages = NULL; GifFile->SColorMap = NULL; Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (Private == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; (void)close(FileHandle); free((char *)GifFile); return NULL; } #if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY) setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ #endif /* __MSDOS__ */ f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ /* MSDOS and Windows32 requires this, no reason not to do it under Unix */ (int)setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream buffer. */ /*@-mustfreeonly@*/ GifFile->Private = (void *)Private; Private->FileHandle = FileHandle; Private->File = f; Private->FileState = FILE_STATE_READ; Private->Read = NULL; /* don't use alternate input method (TVT) */ GifFile->UserData = NULL; /* TVT */ /*@=mustfreeonly@*/ /* Lets see if this is a GIF file: */ if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { _GifError = D_GIF_ERR_READ_FAILED; (void)fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } /* Check for GIF prefix at start of file */ Buf[GIF_STAMP_LEN] = 0; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { _GifError = D_GIF_ERR_NOT_GIF_FILE; fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } _GifError = 0; /* What version of GIF? */ Private->gif89 = (Buf[GIF_VERSION_POS] == '9'); return GifFile; }