• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/processing/JPEG.cpp

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                 // convert the row to YUV
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             // fall through to rgb24
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 };

Generated on Mon Aug 16 2010 14:25:45 for FCam by  doxygen 1.7.1