/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * img_encoder.cc * * Mon Nov 15 19:45:07 CET 2004 * Copyright 2004 Bent Bisballe * deva@aasimon.org ****************************************************************************/ /* * Originally from: * RTVideoRec Realtime video recoder and encoder for Linux * * Copyright (C) 2004 B. Stultiens * Copyright (C) 2004 Koen Otter and Glenn van der Meyden */ /* * This file is part of MIaV. * * MIaV is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MIaV is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MIaV; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* * $Id$ */ /* * $Log$ * Revision 1.9 2005/05/26 12:48:36 deva * *** empty log message *** * * Revision 1.8 2005/05/07 10:25:34 deva * * Removed ffmpeg code from img_encoder and corrected decoding errors in mov_encoder * * Revision 1.7 2005/05/03 08:31:59 deva * Removed the error object, and replaced it with a more generic info object. * * Revision 1.6 2005/05/01 09:56:26 deva * Added Id and Log tags to all files */ #include "img_encoder.h" #include #include "debug.h" // Use libdv #include #include ImgEncoder::ImgEncoder() { } ImgEncoder::~ImgEncoder() { } void ImgEncoder::encode(Frame *dvframe, char *filename, int quality) { // Append suffix.. char fname[256]; sprintf(fname, "%s.jpg", filename); unsigned char rgb[720*576*4]; getRGB(dvframe, rgb); writeJPEGFile(fname, quality, (JSAMPLE*)rgb, 720, 576); } /////////////////////////////////////////////////////////////////////////////////////////// void ImgEncoder::writeJPEGFile(char *filename, int quality, JSAMPLE * image_buffer, // Points to large array of R,G,B-order data int image_width, // Number of columns in image int image_height // Number of rows in image ) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE * outfile; // target file JSAMPROW row_pointer[1]; // pointer to JSAMPLE row[s] int row_stride; // physical row width in image buffer // Step 1: allocate and initialize JPEG compression object cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); // Step 2: specify data destination (eg, a file) if ((outfile = fopen(filename, "wb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); exit(1); } jpeg_stdio_dest(&cinfo, outfile); // Step 3: set parameters for compression cinfo.image_width = image_width; // image width and height, in pixels cinfo.image_height = image_height; cinfo.input_components = 3; // # of color components per pixel //typedef enum { // JCS_UNKNOWN, // error/unspecified // JCS_GRAYSCALE, // monochrome // JCS_RGB, // red/green/blue // JCS_YCbCr, // Y/Cb/Cr (also known as YUV) // JCS_CMYK, // C/M/Y/K // JCS_YCCK // Y/Cb/Cr/K //} J_COLOR_SPACE; cinfo.in_color_space = JCS_RGB; // colorspace of input image jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); // limit to baseline-JPEG values // Step 4: Start compressor jpeg_start_compress(&cinfo, TRUE); // Step 5: while (scan lines remain to be written) row_stride = image_width * 3; // JSAMPLEs per row in image_buffer while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } // Step 6: Finish compression jpeg_finish_compress(&cinfo); fclose(outfile); // Step 7: release JPEG compression object jpeg_destroy_compress(&cinfo); } void ImgEncoder::getRGB(Frame *frame, unsigned char *rgb) { unsigned char *pixels[3]; int pitches[3]; pixels[ 0 ] = rgb; pixels[ 1 ] = NULL; pixels[ 2 ] = NULL; pitches[ 0 ] = 720 * 3; pitches[ 1 ] = 0; pitches[ 2 ] = 0; dv_decoder_t *decoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE); decoder->quality = DV_QUALITY_BEST; dv_parse_header(decoder, frame->data); decoder->system = e_dv_system_625_50; // PAL lines, PAL framerate decoder->sampling = e_dv_sample_422; // 4 bytes y, 2 bytes u, 2 bytes v decoder->std = e_dv_std_iec_61834; decoder->num_dif_seqs = 12; // libdv img decode to rgb dv_decode_full_frame(decoder, frame->data, e_dv_color_rgb, pixels, pitches); dv_decoder_free(decoder); }