"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/qtpng.c" (9 Jan 2007, 6926 Bytes) of package /linux/privat/old/quicktime4linux-2.3-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #include "colormodels.h"
    2 #include "funcprotos.h"
    3 #include <png.h>
    4 #include "quicktime.h"
    5 #include "qtpng.h"
    6 
    7 typedef struct
    8 {
    9     int compression_level;
   10     unsigned char *buffer;
   11 // Read position
   12     long buffer_position;
   13 // Frame size
   14     long buffer_size;
   15 // Buffer allocation
   16     long buffer_allocated;
   17     int quality;
   18     unsigned char *temp_frame;
   19 } quicktime_png_codec_t;
   20 
   21 static int delete_codec(quicktime_video_map_t *vtrack)
   22 {
   23     quicktime_png_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   24     if(codec->buffer) free(codec->buffer);
   25     if(codec->temp_frame) free(codec->temp_frame);
   26     free(codec);
   27     return 0;
   28 }
   29 
   30 static int source_cmodel(quicktime_t *file, int track)
   31 {
   32     int depth = quicktime_video_depth(file, track);
   33     if(depth == 24) 
   34         return BC_RGB888;
   35     else
   36         return BC_RGBA8888;
   37 }
   38 
   39 void quicktime_set_png(quicktime_t *file, int compression_level)
   40 {
   41     int i;
   42     char *compressor;
   43 
   44     for(i = 0; i < file->total_vtracks; i++)
   45     {
   46         if(quicktime_match_32(quicktime_video_compressor(file, i), QUICKTIME_PNG))
   47         {
   48             quicktime_png_codec_t *codec = ((quicktime_codec_t*)file->vtracks[i].codec)->priv;
   49             codec->compression_level = compression_level;
   50         }
   51     }
   52 }
   53 
   54 static void read_function(png_structp png_ptr, png_bytep data, png_uint_32 length)
   55 {
   56     quicktime_png_codec_t *codec = png_get_io_ptr(png_ptr);
   57     
   58     if(length + codec->buffer_position <= codec->buffer_size)
   59     {
   60         memcpy(data, codec->buffer + codec->buffer_position, length);
   61         codec->buffer_position += length;
   62     }
   63 }
   64 
   65 static void write_function(png_structp png_ptr, png_bytep data, png_uint_32 length)
   66 {
   67     quicktime_png_codec_t *codec = png_get_io_ptr(png_ptr);
   68 
   69     if(length + codec->buffer_size > codec->buffer_allocated)
   70     {
   71         codec->buffer_allocated += length;
   72         codec->buffer = realloc(codec->buffer, codec->buffer_allocated);
   73     }
   74     memcpy(codec->buffer + codec->buffer_size, data, length);
   75     codec->buffer_size += length;
   76 }
   77 
   78 static void flush_function(png_structp png_ptr)
   79 {
   80     ;
   81 }
   82 
   83 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
   84 {
   85     int result = 0;
   86     int64_t i;
   87     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
   88     quicktime_trak_t *trak = vtrack->track;
   89     png_structp png_ptr;
   90     png_infop info_ptr;
   91     png_infop end_info = 0; 
   92     int height = trak->tkhd.track_height;
   93     int width = trak->tkhd.track_width;
   94     quicktime_png_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   95     int cmodel = source_cmodel(file, track);
   96     int use_temp = (cmodel != file->color_model ||
   97         file->in_x != 0 ||
   98         file->in_y != 0 ||
   99         file->in_w != width ||
  100         file->in_h != height ||
  101         file->out_w != width ||
  102         file->out_h != height);
  103     unsigned char **temp_rows = malloc(sizeof(unsigned char*) * height);
  104 
  105     if(use_temp)
  106     {
  107         if(!codec->temp_frame)
  108         {
  109             codec->temp_frame = malloc(cmodel_calculate_datasize(width, 
  110                     height, 
  111                     -1, 
  112                     cmodel));
  113         }
  114         for(i = 0; i < height; i++)
  115             temp_rows[i] = codec->temp_frame + 
  116                 cmodel_calculate_pixelsize(cmodel) * width * i;
  117     }
  118     else
  119     {
  120         for(i = 0; i < height; i++)
  121             temp_rows[i] = row_pointers[i];
  122     }
  123 
  124     quicktime_set_video_position(file, vtrack->current_position, track);
  125     codec->buffer_size = quicktime_frame_size(file, vtrack->current_position, track);
  126     codec->buffer_position = 0;
  127     if(codec->buffer_size > codec->buffer_allocated)
  128     {
  129         codec->buffer_allocated = codec->buffer_size;
  130         codec->buffer = realloc(codec->buffer, codec->buffer_allocated);
  131     }
  132 
  133     result = !quicktime_read_data(file, codec->buffer, codec->buffer_size);
  134 
  135     if(!result)
  136     {
  137         png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
  138         info_ptr = png_create_info_struct(png_ptr);
  139         png_set_read_fn(png_ptr, codec, (png_rw_ptr)read_function);
  140         png_read_info(png_ptr, info_ptr);
  141 
  142 /* read the image */
  143         png_read_image(png_ptr, temp_rows);
  144         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
  145     }
  146 
  147     if(use_temp)
  148     {
  149         cmodel_transfer(row_pointers, 
  150             temp_rows,
  151             row_pointers[0],
  152             row_pointers[1],
  153             row_pointers[2],
  154             0,
  155             0,
  156             0,
  157             file->in_x, 
  158             file->in_y, 
  159             file->in_w, 
  160             file->in_h,
  161             0, 
  162             0, 
  163             file->out_w, 
  164             file->out_h,
  165             cmodel, 
  166             file->color_model,
  167             0,
  168             width,
  169             file->out_w);
  170     }
  171 
  172 
  173     free(temp_rows);
  174 
  175     return result;
  176 }
  177 
  178 
  179 
  180 
  181 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
  182 {
  183     int64_t offset = quicktime_position(file);
  184     int result = 0;
  185     int i;
  186     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  187     quicktime_trak_t *trak = vtrack->track;
  188     quicktime_png_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  189     int height = trak->tkhd.track_height;
  190     int width = trak->tkhd.track_width;
  191     png_structp png_ptr;
  192     png_infop info_ptr;
  193     int cmodel = source_cmodel(file, track);
  194     quicktime_atom_t chunk_atom;
  195 
  196     codec->buffer_size = 0;
  197     codec->buffer_position = 0;
  198 
  199     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
  200     info_ptr = png_create_info_struct(png_ptr);
  201     png_set_write_fn(png_ptr,
  202                codec, 
  203                (png_rw_ptr)write_function,
  204                (png_flush_ptr)flush_function);
  205     png_set_compression_level(png_ptr, codec->compression_level);
  206     png_set_IHDR(png_ptr, 
  207         info_ptr, 
  208         width, height,
  209         8, 
  210         cmodel == BC_RGB888 ? 
  211           PNG_COLOR_TYPE_RGB : 
  212           PNG_COLOR_TYPE_RGB_ALPHA, 
  213         PNG_INTERLACE_NONE, 
  214         PNG_COMPRESSION_TYPE_DEFAULT, 
  215         PNG_FILTER_TYPE_DEFAULT);
  216     png_write_info(png_ptr, info_ptr);
  217     png_write_image(png_ptr, row_pointers);
  218     png_write_end(png_ptr, info_ptr);
  219     png_destroy_write_struct(&png_ptr, &info_ptr);
  220 
  221     quicktime_write_chunk_header(file, trak, &chunk_atom);
  222     result = !quicktime_write_data(file, 
  223                 codec->buffer, 
  224                 codec->buffer_size);
  225     quicktime_write_chunk_footer(file, 
  226         trak,
  227         vtrack->current_chunk,
  228         &chunk_atom, 
  229         1);
  230 
  231     vtrack->current_chunk++;
  232     return result;
  233 }
  234 
  235 static int set_parameter(quicktime_t *file, 
  236         int track, 
  237         char *key, 
  238         void *value)
  239 {
  240     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  241     quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
  242     quicktime_png_codec_t *codec = codec_base->priv;
  243 
  244     if(!strcasecmp(key, "compression_level"))
  245         codec->compression_level = *(int*)value;
  246 }
  247 
  248 static int reads_colormodel(quicktime_t *file, 
  249         int colormodel, 
  250         int track)
  251 {
  252     return (colormodel == BC_RGB888 ||
  253         colormodel == BC_BGR8888);
  254 }
  255 
  256 void quicktime_init_codec_png(quicktime_video_map_t *vtrack)
  257 {
  258     quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
  259     quicktime_png_codec_t *codec;
  260 
  261 /* Init public items */
  262     codec_base->priv = calloc(1, sizeof(quicktime_png_codec_t));
  263     codec_base->delete_vcodec = delete_codec;
  264     codec_base->decode_video = decode;
  265     codec_base->encode_video = encode;
  266     codec_base->decode_audio = 0;
  267     codec_base->encode_audio = 0;
  268     codec_base->reads_colormodel = reads_colormodel;
  269     codec_base->set_parameter = set_parameter;
  270     codec_base->fourcc = QUICKTIME_PNG;
  271     codec_base->title = "PNG";
  272     codec_base->desc = "Lossless RGB compression";
  273 
  274 /* Init private items */
  275     codec = codec_base->priv;
  276     codec->compression_level = 9;
  277 }