00001 #include <stdio.h>
00002
00003 extern "C" {
00004 #include <jpeglib.h>
00005 }
00006
00007 #include <FCam/Event.h>
00008 #include <FCam/processing/JPEG.h>
00009 #include <FCam/processing/Demosaic.h>
00010
00011 #include "../Debug.h"
00012
00013 using namespace std;
00014
00015
00016 namespace FCam {
00017 void saveJPEG(Image im, string filename, int quality) {
00018 struct jpeg_compress_struct cinfo;
00019 struct jpeg_error_mgr jerr;
00020
00021 dprintf(DBG_MINOR, "saveJPEG: Saving JPEG to %s, quality %d\n", filename.c_str(), quality);
00022
00023 FILE *f = fopen(filename.c_str(), "wb");
00024 if (!f) {
00025 error(Event::FileSaveError, "saveJPEG: %s: Cannot open file for writing", filename.c_str());
00026 return;
00027 }
00028
00029 cinfo.err = jpeg_std_error(&jerr);
00030 jpeg_create_compress(&cinfo);
00031 jpeg_stdio_dest(&cinfo, f);
00032
00033 cinfo.image_width = im.width();
00034 cinfo.image_height = im.height();
00035 cinfo.input_components = 3;
00036 if (im.type() == RGB24) {
00037 cinfo.in_color_space = JCS_RGB;
00038 } else if (im.type() == YUV24) {
00039 cinfo.in_color_space = JCS_YCbCr;
00040 }
00041
00042 jpeg_set_defaults(&cinfo);
00043 jpeg_set_quality(&cinfo, quality, TRUE);
00044
00045 jpeg_start_compress(&cinfo, TRUE);
00046
00047 if (im.type() == RGB24 || im.type() == YUV24) {
00048 while (cinfo.next_scanline < cinfo.image_height) {
00049 JSAMPLE *row = im(0, cinfo.next_scanline);
00050 jpeg_write_scanlines(&cinfo, &row, 1);
00051 }
00052 } else if (im.type() == UYVY) {
00053 std::vector<JSAMPLE> row(cinfo.image_width*3);
00054 while (cinfo.next_scanline < cinfo.image_height) {
00055
00056 JSAMPLE *rowPtr = &row[0];
00057 unsigned char *dataPtr = im(0, cinfo.next_scanline);
00058 for (size_t i = 0; i < cinfo.image_width/2; i++) {
00059 rowPtr[0] = dataPtr[1];
00060 rowPtr[1] = dataPtr[0];
00061 rowPtr[2] = dataPtr[2];
00062 rowPtr[3] = dataPtr[3];
00063 rowPtr[4] = dataPtr[0];
00064 rowPtr[5] = dataPtr[2];
00065 rowPtr += 6;
00066 dataPtr += 4;
00067 }
00068 rowPtr = &row[0];
00069 jpeg_write_scanlines(&cinfo, &rowPtr, 1);
00070 }
00071 }
00072
00073 jpeg_finish_compress(&cinfo);
00074 fclose(f);
00075 jpeg_destroy_compress(&cinfo);
00076
00077 dprintf(DBG_MINOR, "saveJPEG: Done saving JPEG to %s\n", filename.c_str());
00078 }
00079
00080 void saveJPEG(Frame frame, string filename, int quality) {
00081 if (!frame.image().valid()) {
00082 error(Event::FileSaveError, frame, "saveJPEG: %s: No valid image in frame to save.", filename.c_str());
00083 return;
00084 }
00085
00086 Image im = frame.image();
00087
00088 switch (im.type()) {
00089 case RAW:
00090 im = demosaic(frame);
00091 if (!im.valid()) {
00092 error(Event::FileSaveError, frame, "saveJPEG: %s: Cannot demosaic RAW image to save as JPEG.", filename.c_str());
00093 return;
00094 }
00095
00096 case RGB24: case YUV24: case UYVY:
00097 saveJPEG(im, filename, quality);
00098 break;
00099 default:
00100 error(Event::FileSaveError, frame, "saveJPEG: %s: Unsupported image format", filename.c_str());
00101 break;
00102 }
00103 }
00104 };