Commit 408aa909 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Implemented tiff generation

parent 0353ca66
Loading
Loading
Loading
Loading
+80 −22
Original line number Original line Diff line number Diff line
@@ -79,6 +79,10 @@
 * The file name of Exif buffer
 * The file name of Exif buffer
 * @var file_set::exif_dev_fd
 * @var file_set::exif_dev_fd
 * The file descriptor of Exif buffer
 * The file descriptor of Exif buffer
 * @var file_set::tiff_dev_name
 * The file name of Tiff buffer
 * @var file_set::tiff_dev_fd
 * The file descriptor of Tiff buffer
 * @var file_set::exifmeta_dev_name
 * @var file_set::exifmeta_dev_name
 * The file name of Exif meta buffer
 * The file name of Exif meta buffer
 * @var file_set::exifmeta_dev_fd
 * @var file_set::exifmeta_dev_fd
@@ -92,6 +96,8 @@ struct file_set {
	int            jphead_fd;
	int            jphead_fd;
	const char     *exif_dev_name;
	const char     *exif_dev_name;
	int            exif_dev_fd;
	int            exif_dev_fd;
	const char     *tiff_dev_name;
	int            tiff_dev_fd;
	const char     *exifmeta_dev_name;
	const char     *exifmeta_dev_name;
	int            exifmeta_dev_fd;
	int            exifmeta_dev_fd;
    const char     *framepars_dev_name;
    const char     *framepars_dev_name;
@@ -123,6 +129,11 @@ static const char *exif_dev_names[SENSOR_PORTS] = {
        DEV393_PATH(DEV393_EXIF1),
        DEV393_PATH(DEV393_EXIF1),
        DEV393_PATH(DEV393_EXIF2),
        DEV393_PATH(DEV393_EXIF2),
        DEV393_PATH(DEV393_EXIF3)};
        DEV393_PATH(DEV393_EXIF3)};
static const char *tiff_dev_names[SENSOR_PORTS] = {
        DEV393_PATH(DEV393_TIFF0),
        DEV393_PATH(DEV393_TIFF1),
        DEV393_PATH(DEV393_TIFF2),
        DEV393_PATH(DEV393_TIFF3)};
static const char *exifmeta_dev_names[SENSOR_PORTS] = {
static const char *exifmeta_dev_names[SENSOR_PORTS] = {
        DEV393_PATH(DEV393_EXIF_META0),
        DEV393_PATH(DEV393_EXIF_META0),
        DEV393_PATH(DEV393_EXIF_META1),
        DEV393_PATH(DEV393_EXIF_META1),
@@ -960,17 +971,16 @@ int sendImage(struct file_set *fset, int bufferImageData, int use_Exif, int sav
	int timestamp_start;
	int timestamp_start;


	jpeg_start = lseek(fset->circbuf_fd, 0, SEEK_CUR);     //get the current read pointer
	jpeg_start = lseek(fset->circbuf_fd, 0, SEEK_CUR);     //get the current read pointer
//    jpeg_start = lseek(fset->circbuf_fd, 1, SEEK_CUR)-1;   //just for testing, until rebuilt/rebooted kernel


	D(fprintf(stderr, "jpeg_start (long) = 0x%x\n", jpeg_start));
	D(fprintf(stderr, "jpeg_start (long) = 0x%x\n", jpeg_start));

#if 0
	if (fset->jphead_fd<0)
	if (fset->jphead_fd<0)
	    fset->jphead_fd = open(fset->jphead_fn, O_RDWR);
	    fset->jphead_fd = open(fset->jphead_fn, O_RDWR);
	if (fset->jphead_fd < 0) { // check control OK
	if (fset->jphead_fd < 0) { // check control OK
		fprintf(stderr, "Error opening %s\n", fset->jphead_fn);
		fprintf(stderr, "Error opening %s\n", fset->jphead_fn);
		return -1;
		return -1;
	}
	}
//	fset->jphead_fd = fd_head;

	lseek(fset->jphead_fd, jpeg_start + 1, SEEK_END);              // create JPEG header, find out it's size
	lseek(fset->jphead_fd, jpeg_start + 1, SEEK_END);              // create JPEG header, find out it's size
	head_size = lseek(fset->jphead_fd, 0, SEEK_END);
	head_size = lseek(fset->jphead_fd, 0, SEEK_END);
	if (head_size > JPEG_HEADER_MAXSIZE) {
	if (head_size > JPEG_HEADER_MAXSIZE) {
@@ -979,6 +989,7 @@ int sendImage(struct file_set *fset, int bufferImageData, int use_Exif, int sav
		fset->jphead_fd = -1;
		fset->jphead_fd = -1;
		return -2;
		return -2;
	}
	}
#endif
	/* find total buffer length (it is in defines, actually in c313a.h */
	/* find total buffer length (it is in defines, actually in c313a.h */
	buff_size = lseek(fset->circbuf_fd, 0, SEEK_END); // it is supposed to be open?
	buff_size = lseek(fset->circbuf_fd, 0, SEEK_END); // it is supposed to be open?
	/* restore file poinetr after lseek-ing the end */
	/* restore file poinetr after lseek-ing the end */
@@ -1010,12 +1021,45 @@ int sendImage(struct file_set *fset, int bufferImageData, int use_Exif, int sav
		return -4;
		return -4;
	}
	}


	if (color_mode == COLORMODE_RAW) {
		head_size = 0;
	} else { // some compressed mode
		if (fset->jphead_fd<0)
			fset->jphead_fd = open(fset->jphead_fn, O_RDWR);
		if (fset->jphead_fd < 0) { // check control OK
			fprintf(stderr, "Error opening %s\n", fset->jphead_fn);
			return -1;
		}
		lseek(fset->jphead_fd, jpeg_start + 1, SEEK_END);              // create JPEG header, find out it's size
		head_size = lseek(fset->jphead_fd, 0, SEEK_END);
		if (head_size > JPEG_HEADER_MAXSIZE) {
			fprintf(stderr, "%s:%d: Too big JPEG header (%d > %d)", __FILE__, __LINE__, head_size, JPEG_HEADER_MAXSIZE );
			close(fset->jphead_fd);
			fset->jphead_fd = -1;
			return -2;
		}
	}

    // Copy timestamp (goes after the image data)
    // Copy timestamp (goes after the image data)
    timestamp_start=jpeg_start+((jpeg_len+CCAM_MMAP_META+3) & (~0x1f)) + 32 - CCAM_MMAP_META_SEC; // magic shift - should index first byte of the time stamp
    timestamp_start=jpeg_start+((jpeg_len+CCAM_MMAP_META+3) & (~0x1f)) + 32 - CCAM_MMAP_META_SEC; // magic shift - should index first byte of the time stamp
    if (timestamp_start >= buff_size) timestamp_start-=buff_size;
    if (timestamp_start >= buff_size) timestamp_start-=buff_size;
    memcpy (&(frame_params.timestamp_sec), (unsigned long * ) &ccam_dma_buf[timestamp_start>>2],8);
    memcpy (&(frame_params.timestamp_sec), (unsigned long * ) &ccam_dma_buf[timestamp_start>>2],8);

    if (color_mode == COLORMODE_RAW) {
	if (use_Exif) {
		if (fset->tiff_dev_fd <0)
		    fset->tiff_dev_fd = open(fset->tiff_dev_name, O_RDONLY);
		if (fset->tiff_dev_fd < 0) {                                 // check control OK
			fprintf(stderr, "Error opening %s\n", fset->tiff_dev_name);
			close(fset->jphead_fd);
			fset->jphead_fd = -1;
			return -5;
		}
		exifDataSize = lseek(fset->tiff_dev_fd, 1, SEEK_END);  // at the beginning of page 1 - position == page length
		if (exifDataSize < 0) exifDataSize = 0;                // error from lseek;
		if (!exifDataSize){
		    close(fset->tiff_dev_fd);
		    fset->tiff_dev_fd = -1;
		}
    } else if (use_Exif) {
		D(fprintf(stderr,"frame_params.meta_index=0x%x\n",(int) frame_params.meta_index));
		D(fprintf(stderr,"frame_params.meta_index=0x%x\n",(int) frame_params.meta_index));
		// read Exif to buffer:
		// read Exif to buffer:
		if (fset->exif_dev_fd <0)
		if (fset->exif_dev_fd <0)
@@ -1041,7 +1085,7 @@ int sendImage(struct file_set *fset, int bufferImageData, int use_Exif, int sav
	// Get metadata, update Exif and JFIF headers if ep and ed pointers are non-zero (NULL will generate files with JFIF-only headers)
	// Get metadata, update Exif and JFIF headers if ep and ed pointers are non-zero (NULL will generate files with JFIF-only headers)
	// Now we always malloc buffer, before - only for bimg, using fixed-size header buffer - was it faster?
	// Now we always malloc buffer, before - only for bimg, using fixed-size header buffer - was it faster?


	jpeg_full_size = jpeg_len + head_size + 2 + exifDataSize;
	jpeg_full_size = jpeg_len + head_size + exifDataSize + ((head_size > 0) ? 2 : 0);


//	fprintf(stderr, "jpeg_len = 0x%x, head_size = 0x%x, exifDataSize = 0x%x, jpeg_full_size = 0x%x\n",
//	fprintf(stderr, "jpeg_len = 0x%x, head_size = 0x%x, exifDataSize = 0x%x, jpeg_full_size = 0x%x\n",
//			jpeg_len, head_size, exifDataSize, jpeg_full_size);
//			jpeg_len, head_size, exifDataSize, jpeg_full_size);
@@ -1064,6 +1108,12 @@ int sendImage(struct file_set *fset, int bufferImageData, int use_Exif, int sav
		}
		}
	}
	}


	if (color_mode == COLORMODE_RAW) {
		lseek(fset->tiff_dev_fd, frame_params.meta_index,SEEK_END);   // select meta page to use (matching frame)
		read (fset->tiff_dev_fd, &jpeg_copy[0], exifDataSize);        // Read Tiff header
		close(fset->tiff_dev_fd);
		fset->tiff_dev_fd = -1;
	} else {
		lseek(fset->jphead_fd, 0, 0);
		lseek(fset->jphead_fd, 0, 0);
		read(fset->jphead_fd, &jpeg_copy[exifDataSize], head_size);
		read(fset->jphead_fd, &jpeg_copy[exifDataSize], head_size);
		close(fset->jphead_fd);
		close(fset->jphead_fd);
@@ -1075,9 +1125,14 @@ int sendImage(struct file_set *fset, int bufferImageData, int use_Exif, int sav
			close(fset->exif_dev_fd);
			close(fset->exif_dev_fd);
			fset->exif_dev_fd = -1;
			fset->exif_dev_fd = -1;
		}
		}
	}
	switch (color_mode) {
	switch (color_mode) {
	//   case COLORMODE_MONO6:    //! monochrome, (4:2:0),
	//   case COLORMODE_MONO6:    //! monochrome, (4:2:0),
	//   case COLORMODE_COLOR:    //! color, 4:2:0, 18x18(old)
	//   case COLORMODE_COLOR:    //! color, 4:2:0, 18x18(old)
	case COLORMODE_RAW:     // jp4, original (4:2:0)
		mime_type = "tiff";
		extension = "tiff";
		break;
	case COLORMODE_JP46:    // jp4, original (4:2:0)
	case COLORMODE_JP46:    // jp4, original (4:2:0)
	case COLORMODE_JP46DC:  // jp4, dc -improved (4:2:0)
	case COLORMODE_JP46DC:  // jp4, dc -improved (4:2:0)
		mime_type = "jp46";
		mime_type = "jp46";
@@ -1114,6 +1169,7 @@ int sendImage(struct file_set *fset, int bufferImageData, int use_Exif, int sav
   #define COLORMODE_JP4DIFF2  9 // jp4, 4 blocks, differential, divide differences by 2: red := (R-G1)/2, blue:=(B-G1)/2, green=G1, green2 (G2-G1)/2
   #define COLORMODE_JP4DIFF2  9 // jp4, 4 blocks, differential, divide differences by 2: red := (R-G1)/2, blue:=(B-G1)/2, green=G1, green2 (G2-G1)/2
   #define COLORMODE_JP4HDR2  10 // jp4, 4 blocks, differential HDR: red := (R-G1)/2, blue:=(B-G1)/2, green=G1, green2 (high gain)=G2),
   #define COLORMODE_JP4HDR2  10 // jp4, 4 blocks, differential HDR: red := (R-G1)/2, blue:=(B-G1)/2, green=G1, green2 (high gain)=G2),
   #define COLORMODE_MONO4    14 // monochrome, 4 blocks (but still with 2x2 macroblocks)
   #define COLORMODE_MONO4    14 // monochrome, 4 blocks (but still with 2x2 macroblocks)
   #define COLORMODE_RAW      15 // raw 8/16-bit data in scanline order, bypassing compressor
	 */
	 */
	printf("Content-Type: image/%s\r\n", mime_type);
	printf("Content-Type: image/%s\r\n", mime_type);
    if (saveImage) {
    if (saveImage) {
@@ -1144,7 +1200,7 @@ int sendImage(struct file_set *fset, int bufferImageData, int use_Exif, int sav
		end_time = lseek(fset->circbuf_fd, LSEEK_CIRC_UTIME, SEEK_END);
		end_time = lseek(fset->circbuf_fd, LSEEK_CIRC_UTIME, SEEK_END);
		D(fprintf(stderr, "memcpy time = %lu\n", end_time - start_time));
		D(fprintf(stderr, "memcpy time = %lu\n", end_time - start_time));
#endif
#endif
		memcpy(&jpeg_copy[jpeg_len + head_size + exifDataSize], trailer, 2);
		if (color_mode != COLORMODE_RAW) memcpy(&jpeg_copy[jpeg_len + head_size + exifDataSize], trailer, 2); // Only for JPEG flavors
		printf("Content-Length: %d\r\n", jpeg_full_size);
		printf("Content-Length: %d\r\n", jpeg_full_size);
		printf("\r\n");
		printf("\r\n");
		sendBuffer(jpeg_copy, jpeg_full_size);
		sendBuffer(jpeg_copy, jpeg_full_size);
@@ -1164,7 +1220,7 @@ int sendImage(struct file_set *fset, int bufferImageData, int use_Exif, int sav
			sendBuffer((void*)&ccam_dma_buf[jpeg_start >> 2], jpeg_len);
			sendBuffer((void*)&ccam_dma_buf[jpeg_start >> 2], jpeg_len);
            D1(fprintf(stderr, "One part (non-buffered), jpeg_start (long) = 0x%x, buff_size = 0x%x\n", jpeg_start, buff_size));
            D1(fprintf(stderr, "One part (non-buffered), jpeg_start (long) = 0x%x, buff_size = 0x%x\n", jpeg_start, buff_size));
		}
		}
		sendBuffer(trailer, 2);
		if (color_mode != COLORMODE_RAW) sendBuffer(trailer, 2); // Only for JPEG flavors
	}
	}
	free(jpeg_copy);
	free(jpeg_copy);
	return 0;
	return 0;
@@ -1513,6 +1569,8 @@ void init_file_set(struct file_set *fset, int fset_sz)
		fset[i].jphead_fd = -1;
		fset[i].jphead_fd = -1;
		fset[i].exif_dev_name = exif_dev_names[i];
		fset[i].exif_dev_name = exif_dev_names[i];
		fset[i].exif_dev_fd = -1;
		fset[i].exif_dev_fd = -1;
		fset[i].tiff_dev_name = tiff_dev_names[i];
		fset[i].tiff_dev_fd = -1;
		fset[i].exifmeta_dev_name = exifmeta_dev_names[i];
		fset[i].exifmeta_dev_name = exifmeta_dev_names[i];
		fset[i].exifmeta_dev_fd = -1;
		fset[i].exifmeta_dev_fd = -1;
        fset[i].framepars_dev_name = framepars_dev_names[i];
        fset[i].framepars_dev_name = framepars_dev_names[i];