File indexing completed on 2024-12-22 04:17:13
0001 /*************************************************************************** 0002 * * 0003 * copyright : (C) 2015 C. Barth Netterfield * 0004 * netterfield@astro.utoronto.ca * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 ***************************************************************************/ 0012 #include <stdio.h> 0013 #include <stdlib.h> 0014 #include <string.h> 0015 #include <sys/types.h> 0016 #include <sys/stat.h> 0017 #include <fcntl.h> 0018 #include <unistd.h> 0019 0020 #include "bis.h" 0021 0022 char *BIS_ERRORSTR[] = {"OK", "Could not open file", "Unknown file format"}; 0023 0024 0025 BISfile *BISopen(char *filename) { 0026 BISfile *bis; 0027 int nr; 0028 unsigned short us_in; 0029 0030 bis = (BISfile*) malloc(sizeof(BISfile)); 0031 0032 bis->status = BIS_OK; 0033 0034 bis->fileName = malloc (strlen(filename)+1); 0035 0036 strcpy(bis->fileName,filename); 0037 0038 bis->fp = open(filename, O_RDONLY); 0039 0040 if (bis->fp<0) { 0041 bis->status = BIS_NOOPEN; 0042 return (bis); 0043 } 0044 0045 nr = read(bis->fp, &us_in,2); 0046 bis->formatType = us_in; 0047 nr += read(bis->fp, &us_in,2); 0048 bis->frameSize = us_in; 0049 0050 switch (bis->formatType) { 0051 case 0xe6b0: 0052 bis->imagesPerFrame = 5; 0053 break; 0054 default: 0055 bis->status = BIS_UNKNOWN; 0056 break; 0057 } 0058 0059 return (bis); 0060 } 0061 0062 0063 void BISclose(BISfile *bis) { 0064 if ((bis->fp>0) && (bis->status!=BIS_NOOPEN)) { 0065 close(bis->fp); 0066 } 0067 free(bis->fileName); 0068 free(bis); 0069 } 0070 0071 0072 /* initialize the image into a empty image, ready for use */ 0073 /* this is essentially a constructor, and should be called on */ 0074 /* any new bis image before use! */ 0075 void BISInitImage(BISimage *image) { 0076 image->w = image->h = image->x = image->y = 0; 0077 image->allocated = 0; 0078 image->img = NULL; 0079 } 0080 0081 0082 /* free any memory allocated to the bis image */ 0083 /* note: the image is still valid and can be used again */ 0084 /* without calling BISInitImage */ 0085 void BISFreeImage(BISimage *image) { 0086 if (image->img) { 0087 free(image->img); 0088 } 0089 BISInitImage(image); 0090 } 0091 0092 0093 int isBISfile(char *filename) { 0094 BISfile *bis; 0095 int is_bis; 0096 0097 bis = BISopen(filename); 0098 is_bis = (bis->status == BIS_OK); 0099 BISclose(bis); 0100 0101 return (is_bis); 0102 } 0103 0104 int BISnframes(BISfile *bis) { 0105 off_t bytes; 0106 0107 bytes = lseek(bis->fp,0,SEEK_END); 0108 0109 if (bytes<0) bytes = 0L; 0110 0111 if (bis->frameSize >0L) { 0112 //return (bytes); 0113 return ((bytes-4L)/bis->frameSize); 0114 } else { 0115 return 0; 0116 } 0117 } 0118 0119 int BISreadimage(BISfile *bis, int frame, int i_img, BISimage *I) { 0120 int nframes; 0121 //unsigned short us_in[5]; 0122 unsigned short image_offsets[5]; 0123 unsigned short image_dim[4]; 0124 int nr; 0125 int img_size; 0126 0127 nframes = BISnframes(bis); 0128 if (frame < 0) { // last frame 0129 frame = nframes - 1; 0130 } 0131 0132 if ((frame >= nframes) || (nframes<1)) { // can't read past end; 0133 I->w = I->h = I->x = I->y = 0; 0134 return 0; 0135 } 0136 0137 if (i_img >= bis->imagesPerFrame) { 0138 I->w = I->h = I->x = I->y = 0; 0139 return 0; 0140 } 0141 0142 // read the image offsets 0143 off_t offset = (off_t)frame * (off_t)bis->frameSize + 4L; 0144 //lseek(bis->fp, frame*bis->frameSize+4, SEEK_SET); 0145 lseek(bis->fp, offset, SEEK_SET); 0146 nr = read(bis->fp, &image_offsets, 10); // read offsets 0147 if ((nr!=10) || (image_offsets[i_img] <1)) { 0148 I->w = I->h = I->x = I->y = 0; 0149 return 0; 0150 } 0151 0152 // Sanity check: offset points to the beginning of the frame 0153 // image_offsets[i_img] + offset points to the start of the image. 0154 // so image_offsets[i_img] had better be smaller than frameSize - 8 for 0155 // a 0 size image. FIXME: tighter constraint? 0156 if (image_offsets[i_img] > bis->frameSize- 8) { 0157 I->w = I->h = I->x = I->y = 0; 0158 return 0; 0159 } 0160 0161 // Read the image size and position data 0162 //lseek(bis->fp, frame*bis->frameSize+4+us_in[i_img], SEEK_SET); 0163 lseek(bis->fp, offset+(off_t)image_offsets[i_img], SEEK_SET); 0164 nr = read(bis->fp, &image_dim, 8); // read image dimensions 0165 if (nr!=8) { 0166 I->w = I->h = I->x = I->y = 0; 0167 return 0; 0168 } 0169 I->w = image_dim[0]; 0170 I->h = image_dim[1]; 0171 I->x = image_dim[2]; 0172 I->y = image_dim[3]; 0173 0174 if ((I->w < 1) || (I->h < 1)) { 0175 I->w = I->h = I->x = I->y = 0; 0176 return 0; 0177 } 0178 0179 // read the image 0180 img_size = I->w * I->h; 0181 0182 // Sanity Check: 0183 // image_size + image_offsets[i_image] + 8 had better be smaller than 0184 // frameSize in order to fit in the frame. 0185 if (image_offsets[i_img] + img_size > bis->frameSize- 8) { 0186 I->w = I->h = I->x = I->y = 0; 0187 return 0; 0188 } 0189 0190 if (img_size > I->allocated) { 0191 I->img = realloc(I->img, img_size+1); 0192 I->allocated = img_size; 0193 } 0194 0195 nr = read(bis->fp, I->img, img_size); // read image 0196 if (nr != img_size) { 0197 I->w = I->h = I->x = I->y = 0; 0198 return 0; 0199 } 0200 0201 return 1; 0202 } 0203