File indexing completed on 2024-12-29 04:11:47
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 #include <stdint.h> 0020 0021 #include "its.h" 0022 0023 char *ITS_ERRORSTR[] = {"OK", "Could not open file", "Unknown file format"}; 0024 0025 0026 ITSfile *ITSopen(char *filename) { 0027 ITSfile *its; 0028 char *index_filename; 0029 0030 its = (ITSfile*) malloc(sizeof(ITSfile)); 0031 0032 its->status = ITS_OK; 0033 0034 its->fileName = malloc (strlen(filename)+1); 0035 index_filename = malloc (strlen(filename)+5); 0036 0037 sprintf(index_filename, "%s.its", filename); 0038 strcpy(its->fileName,filename); 0039 0040 its->fp_data = open(filename, O_RDONLY); 0041 if (its->fp_data<0) { 0042 its->status = ITS_NOOPEN; 0043 free(index_filename); 0044 return (its); 0045 } 0046 0047 its->fp_index = open(index_filename, O_RDONLY); 0048 free(index_filename); 0049 if (its->fp_index<0) { 0050 its->status = ITS_NOOPEN; 0051 return (its); 0052 } 0053 0054 return (its); 0055 } 0056 0057 0058 void ITSclose(ITSfile *its) { 0059 if (its->status != ITS_NOOPEN) { 0060 if (its->fp_index > 0) { 0061 close(its->fp_index); 0062 } 0063 if (its->fp_data > 0) { 0064 close(its->fp_data); 0065 } 0066 } 0067 0068 free(its->fileName); 0069 free(its); 0070 } 0071 0072 0073 /* initialize the image into a empty image, ready for use */ 0074 /* this is essentially a constructor, and should be called on */ 0075 /* any new its image before use! */ 0076 void ITSInitImage(ITSimage *image) { 0077 image->w = image->h = image->x = image->y = 0; 0078 image->allocated = 0; 0079 image->img = NULL; 0080 } 0081 0082 0083 /* free any memory allocated to the its image */ 0084 /* note: the image is still valid and can be used again */ 0085 /* without calling ITSInitImage */ 0086 void ITSFreeImage(ITSimage *image) { 0087 if (image->img) { 0088 free(image->img); 0089 } 0090 ITSInitImage(image); 0091 } 0092 0093 0094 int isITSfile(char *filename) { 0095 ITSfile *its; 0096 int is_its; 0097 0098 its = ITSopen(filename); 0099 is_its = (its->status == ITS_OK); 0100 ITSclose(its); 0101 0102 return (is_its); 0103 } 0104 0105 int checkHeader(unsigned char *h) { 0106 unsigned char sw[] = {0xeb, 0x90, 0x14, 0x6f, 0x00}; 0107 unsigned char crc = 0; 0108 int i; 0109 0110 for (i=0; i<5; i++) { 0111 if (h[i] != sw[i]) { 0112 fprintf(stderr, "bad byte %d in checkHeader\n", i); 0113 return (0); 0114 } 0115 } 0116 for (i=0; i<14; i++) { 0117 crc ^= h[i]; 0118 } 0119 if (crc != h[14]) { 0120 fprintf(stderr, "bad checksum in header\n"); 0121 return 0; 0122 } 0123 0124 return(1); 0125 } 0126 0127 // how many frames in the file? Check the length of the index. 0128 int ITSnframes(ITSfile *its) { 0129 off_t bytes; 0130 0131 bytes = lseek(its->fp_index,0,SEEK_END); 0132 0133 if (bytes<0) bytes = 0L; 0134 0135 return (bytes/INDEX_WORD_SIZE); 0136 } 0137 0138 int ITSreadimage(ITSfile *its, int frame, int i_img, ITSimage *I) { 0139 int nframes; 0140 off_t offset; 0141 int nr; 0142 uint64_t index; 0143 unsigned char buf_in[1024]; 0144 unsigned short w, h; 0145 unsigned char ni; 0146 int img_size; 0147 0148 nframes = ITSnframes(its); 0149 if (frame < 0) { // last frame 0150 frame = nframes - 1; 0151 } 0152 0153 if ((frame >= nframes) || (nframes<1)) { // can't read past end; 0154 I->w = I->h = I->x = I->y = 0; 0155 return 0; 0156 } 0157 0158 // First read the index file to find the index. 0159 offset = lseek(its->fp_index,frame*INDEX_WORD_SIZE, SEEK_SET); 0160 if (offset != frame*INDEX_WORD_SIZE) { 0161 I->w = I->h = I->x = I->y = 0; 0162 return 0; 0163 } 0164 0165 nr = read(its->fp_index, &index, INDEX_WORD_SIZE); 0166 if (nr != INDEX_WORD_SIZE) { 0167 I->w = I->h = I->x = I->y = 0; 0168 return 0; 0169 } 0170 0171 // Second: read the header in the data file 0172 offset = lseek(its->fp_data, index, SEEK_SET); 0173 if (offset != index) { 0174 I->w = I->h = I->x = I->y = 0; 0175 return 0; 0176 } 0177 0178 nr = read(its->fp_data, buf_in, 15); 0179 if (nr != 15) { 0180 I->w = I->h = I->x = I->y = 0; 0181 return 0; 0182 } 0183 0184 if (!checkHeader(buf_in)) { 0185 I->w = I->h = I->x = I->y = 0; 0186 return 0; 0187 } 0188 0189 w = *((unsigned short *)(buf_in+9)); 0190 h = *((unsigned short *)(buf_in+11)); 0191 ni = *((unsigned char *)(buf_in+13)); 0192 0193 if (i_img >= ni) { 0194 I->w = I->h = I->x = I->y = 0; 0195 return 0; 0196 } 0197 0198 img_size = w * h; 0199 if (I->allocated < img_size) { 0200 I->img = realloc(I->img, img_size+1); 0201 I->allocated = img_size; 0202 } 0203 0204 // Now read in the actual image 0205 offset = lseek(its->fp_data, i_img*(img_size + 4), SEEK_CUR); 0206 if (offset>=0) { 0207 nr = read(its->fp_data, &(I->x), 2); 0208 nr += read(its->fp_data, &(I->y), 2); 0209 nr += read(its->fp_data, I->img, img_size); 0210 } 0211 if ((offset<0) || (nr != img_size + 4)) { 0212 I->w = I->h = I->x = I->y = 0; 0213 return 0; 0214 } 0215 0216 I->w = w; 0217 I->h = h; 0218 0219 return 1; 0220 } 0221