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