root/platform/generic/filewrite.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. filewrite_get_jpeg_chunk
  2. filewrite_set_discard_jpeg
  3. filewrite_main_hook
  4. filewrite_jpeg_complete
  5. remotecap_jpeg_chunks_done
  6. fwt_open
  7. fwt_write
  8. fwt_lseek
  9. fwt_close
  10. fwt_after_close

   1 #include "stdlib.h" // for NULL
   2 
   3 #include "remotecap_core.h"
   4 static int ignore_current_write=0; //used by the platform routine to check whether to write the current file
   5 #ifdef CAM_DRYOS
   6 static long fwt_bytes_written = 0; // need to track this independently of ptp
   7 volatile int current_write_ignored=0; //needed to prevent nasty surprises with the current override code
   8 #endif //CAM_DRYOS
   9 
  10 /*
  11 handle camera specific MAX_CHUNKS_FOR_JPEG, camp_ptp_data_chunk
  12 get address and size of chunk N
  13 returns NULL addr and zero size when max chunks reached
  14 */
  15 static cam_ptp_data_chunk *jpeg_chunks;
  16 #ifdef CAM_FILEWRITETASK_MULTIPASS
  17 static int jpeg_curr_session_chunk;
  18 #ifdef CAM_FILEWRITETASK_SEEKS
  19 static int jpeg_bytes_left;
  20 static int jpeg_file_offset;
  21 static int jpeg_full_size;
  22 #else
  23 static int jpeg_last_session;
  24 #endif
  25 #endif
  26 
  27 /*
  28 called by ptp task (via remotecap.c code) to fetch chunks of jpeg data
  29 */
  30 int filewrite_get_jpeg_chunk(char **addr,int *size,unsigned n,int *pos) {
  31     *pos=-1;
  32 #if !defined(CAM_FILEWRITETASK_MULTIPASS)
  33     // TODO null should probably be an error
  34     if (n >= MAX_CHUNKS_FOR_JPEG || jpeg_chunks == NULL) {
  35         *addr=(char *)0xFFFFFFFF; // signals last chunk
  36         *size=0;
  37         return REMOTECAP_JPEG_CHUNK_STATUS_LAST; // last chunk
  38     }
  39     *addr=(char *)jpeg_chunks[n].address;
  40     *size=jpeg_chunks[n].length;
  41     if (n < MAX_CHUNKS_FOR_JPEG-1) {
  42         if (jpeg_chunks[n+1].length==0) {
  43             return REMOTECAP_JPEG_CHUNK_STATUS_LAST; // last chunk
  44         }
  45         return REMOTECAP_JPEG_CHUNK_STATUS_MORE; // not last chunk
  46     }
  47     return REMOTECAP_JPEG_CHUNK_STATUS_LAST; // last chunk
  48 #else
  49     if ( jpeg_chunks == NULL ) { //do we have a valid queue?
  50         int m=50;
  51         while (m>0) { //wait for at most 500ms
  52             _SleepTask(10);
  53             m--;
  54             if ( jpeg_chunks != NULL ) break;
  55         }
  56         if ( jpeg_chunks == NULL ) { //timeout, error
  57             *addr=(char *)0;
  58             *size=0;
  59             return REMOTECAP_JPEG_CHUNK_STATUS_LAST;
  60         }
  61     }
  62     *addr=(char *)jpeg_chunks[jpeg_curr_session_chunk].address;
  63     *size=jpeg_chunks[jpeg_curr_session_chunk].length;
  64 #ifdef CAM_FILEWRITETASK_SEEKS
  65     if ( n == 0 ) { // first chunk for this shot
  66         jpeg_bytes_left = jpeg_full_size;
  67     }
  68     jpeg_bytes_left -= *size;
  69     if (jpeg_curr_session_chunk == 0) {
  70         *pos=jpeg_file_offset; //only post file offset for the first chunk in the current queue
  71     }
  72 #else
  73     if ((jpeg_curr_session_chunk==0) && (jpeg_last_session)) {
  74         *pos=0; //only post file offset for the first chunk in the last queue
  75     }
  76 #endif
  77     jpeg_curr_session_chunk++;
  78 #ifdef CAM_FILEWRITETASK_SEEKS
  79     if (jpeg_bytes_left>0) {
  80         if ( jpeg_curr_session_chunk < MAX_CHUNKS_FOR_JPEG ) {
  81             if (jpeg_chunks[jpeg_curr_session_chunk].length==0) { //last chunk of the current queue
  82                 return REMOTECAP_JPEG_CHUNK_STATUS_SESS_LAST;
  83             }
  84             return REMOTECAP_JPEG_CHUNK_STATUS_MORE; //not last
  85         }
  86         else {
  87             return REMOTECAP_JPEG_CHUNK_STATUS_SESS_LAST;
  88         }
  89     }
  90 #else
  91     if ( jpeg_curr_session_chunk < MAX_CHUNKS_FOR_JPEG ) {
  92         if (jpeg_chunks[jpeg_curr_session_chunk].length==0) { //last chunk of the current queue
  93             if (jpeg_last_session) {
  94                 return REMOTECAP_JPEG_CHUNK_STATUS_LAST;
  95             }
  96             else {
  97                 return REMOTECAP_JPEG_CHUNK_STATUS_SESS_LAST;
  98             }
  99         }
 100         return REMOTECAP_JPEG_CHUNK_STATUS_MORE; //not last
 101     }
 102     else {
 103         if (jpeg_last_session) {
 104             return REMOTECAP_JPEG_CHUNK_STATUS_LAST;
 105         }
 106         else {
 107             return REMOTECAP_JPEG_CHUNK_STATUS_SESS_LAST;
 108         }
 109     }
 110 #endif
 111     return REMOTECAP_JPEG_CHUNK_STATUS_LAST; //last
 112 #endif //CAM_FILEWRITETASK_MULTIPASS
 113 }
 114 
 115 void filewrite_set_discard_jpeg(int state) {
 116     ignore_current_write = state;
 117 }
 118 
 119 void filewrite_main_hook(fwt_data_struct *fwt_data)
 120 {
 121 #ifdef CAM_FILEWRITETASK_MULTIPASS
 122     jpeg_curr_session_chunk = 0;
 123 #ifdef CAM_FILEWRITETASK_SEEKS
 124     // don't forget to #define FWT_SEEKMASK, FWT_MUSTSEEK
 125     /*
 126      * below information is only valid when this routine is called
 127      *
 128      * seek flag is at offset 0x50 for DryOS r50
 129      * 2: seek is needed
 130      * if not 2, seek is only performed when file_offset is not 0
 131      *
 132      * seek flag is at offset 0x4c for DryOS r51
 133      * if (seek_flag & 0x40) == 0x40 then seek is needed
 134      * otherwise, seek is only performed when file_offset is not 0
 135      */
 136     if ( ((fwt_data->seek_flag & FWT_SEEKMASK) == FWT_MUSTSEEK) || (fwt_data->file_offset != 0) ) {
 137         jpeg_file_offset = fwt_data->file_offset;
 138     }
 139     else {
 140         jpeg_file_offset = -1; // no seek needed
 141     }
 142     jpeg_full_size = fwt_data->full_size;
 143 #else
 144     /*
 145      * below information is only valid when this routine is called
 146      *
 147      * we need to watch the file open flags to determine whether the jpeg data arrives in multiple passes
 148      * if the flag isn't there, it's the last (or only) pass
 149      */
 150     if (fwt_data->oflags & OFLAG_NOFLUSH) {
 151         jpeg_last_session = 0;
 152     }
 153     else {
 154         jpeg_last_session = 1;
 155     }
 156 #endif // CAM_FILEWRITETASK_SEEKS
 157 #endif // CAM_FILEWRITETASK_MULTIPASS
 158     jpeg_chunks = &(fwt_data->pdc[0]);
 159     remotecap_jpeg_available();
 160     jpeg_chunks=NULL;
 161 }
 162 
 163 // called from filewrite when the hook has returned for the last time for a given file
 164 // to clear ignored write and tell remotecap raw hook it's ok to proceed to next shot
 165 // returns whether the write was ignored, for simpler asm code on the cams that need to switch filename
 166 int filewrite_jpeg_complete(void) {
 167     if(ignore_current_write) {
 168 #ifdef CAM_DRYOS
 169 #ifdef CAM_FILEWRITETASK_SEEKS
 170         if (fwt_bytes_written < jpeg_full_size) {
 171             return 1;
 172         }
 173 #elif defined(CAM_FILEWRITETASK_MULTIPASS)
 174         if (!jpeg_last_session) {
 175             return 1;
 176         }
 177 #endif // CAM_FILEWRITETASK_SEEKS, CAM_FILEWRITETASK_MULTIPASS
 178         current_write_ignored=0;
 179         fwt_bytes_written = 0;
 180 #endif // CAM_DRYOS
 181         ignore_current_write=0;
 182         remotecap_type_complete(1); //PTP_CHDK_CAPTURE_JPG
 183         return 1;
 184     }
 185     return 0;
 186 }
 187 
 188 #ifdef CAM_FILEWRITETASK_MULTIPASS
 189 void remotecap_jpeg_chunks_done() {
 190     jpeg_chunks=NULL;
 191 }
 192 #endif // CAM_FILEWRITETASK_MULTIPASS
 193 
 194 // wrapper functions for use in filewritetask
 195 #ifdef CAM_DRYOS
 196 int fwt_open(const char *name, int flags, int mode) {
 197     if (!ignore_current_write) {
 198         return _Open(name, flags, mode);
 199     }
 200     current_write_ignored=1;
 201     return 255; // fake, invalid file descriptor
 202 }
 203 
 204 int fwt_write(int fd, const void *buffer, long nbytes) {
 205     if (!current_write_ignored) {
 206         return _Write(fd, buffer, nbytes);
 207     }
 208     fwt_bytes_written += nbytes;
 209     return (int)nbytes; // "everything's written"
 210 }
 211 
 212 #ifdef CAM_FILEWRITETASK_SEEKS
 213 int fwt_lseek(int fd, long offset, int whence) {
 214     if (!current_write_ignored) {
 215         return _lseek(fd, offset, whence);
 216     }
 217     return (int)offset; // "file position set to the requested value"
 218 }
 219 #endif // CAM_FILEWRITETASK_SEEKS
 220 
 221 int fwt_close (int fd) {
 222     if (!current_write_ignored) {
 223         int ret = _Close(fd);
 224         //imagesavecomplete=1;
 225         fwt_bytes_written = 0;
 226         return ret;
 227     }
 228     filewrite_jpeg_complete();
 229     return 0;
 230 }
 231 #else // ifdef CAM_DRYOS
 232 /*
 233  * helper function for VxWorks camera
 234  * to be used when imagesavecomplete handling is needed
 235  */
 236 int fwt_after_close (int param) {
 237 //    imagesavecomplete=1;
 238     return param;
 239 }
 240 #endif //CAM_DRYOS

/* [<][>][^][v][top][bottom][index][help] */