"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/jpeg.c" (9 Jan 2007, 10169 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 <stdio.h>
    2 #include <stdlib.h>
    3 #include <unistd.h>
    4 #include "colormodels.h"
    5 #include "funcprotos.h"
    6 #include "jpeg.h"
    7 #include "libmjpeg.h"
    8 #include "quicktime.h"
    9 
   10 // Jpeg types
   11 #define JPEG_PROGRESSIVE 0
   12 #define JPEG_MJPA 1
   13 #define JPEG_MJPB 2
   14 
   15 typedef struct
   16 {
   17     unsigned char *buffer;
   18     long buffer_allocated;
   19     long buffer_size;
   20     mjpeg_t *mjpeg;
   21     int jpeg_type;
   22     unsigned char *temp_video;
   23     int initialized;
   24     int quality;
   25     int use_float;
   26 } quicktime_jpeg_codec_t;
   27 
   28 static int delete_codec(quicktime_video_map_t *vtrack)
   29 {
   30     quicktime_jpeg_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   31     int i;
   32 
   33     if(codec->mjpeg) mjpeg_delete(codec->mjpeg);
   34     if(codec->buffer)
   35         free(codec->buffer);
   36     if(codec->temp_video)
   37         free(codec->temp_video);
   38     free(codec);
   39     return 0;
   40 }
   41 
   42 void quicktime_set_jpeg(quicktime_t *file, int quality, int use_float)
   43 {
   44     int i;
   45     char *compressor;
   46 
   47 printf("1\n");
   48     for(i = 0; i < file->total_vtracks; i++)
   49     {
   50         if(quicktime_match_32(quicktime_video_compressor(file, i), QUICKTIME_JPEG) ||
   51             quicktime_match_32(quicktime_video_compressor(file, i), QUICKTIME_MJPA) ||
   52             quicktime_match_32(quicktime_video_compressor(file, i), QUICKTIME_RTJ0))
   53         {
   54             quicktime_jpeg_codec_t *codec = ((quicktime_codec_t*)file->vtracks[i].codec)->priv;
   55             codec->quality = quality;
   56             codec->use_float = use_float;
   57         }
   58     }
   59 printf("10\n");
   60 }
   61 
   62 
   63 static void initialize(quicktime_video_map_t *vtrack)
   64 {
   65     quicktime_jpeg_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   66     if(!codec->initialized)
   67     {
   68 /* Init private items */
   69         codec->mjpeg = mjpeg_new(vtrack->track->tkhd.track_width, 
   70             vtrack->track->tkhd.track_height, 
   71             1 + (codec->jpeg_type == JPEG_MJPA || codec->jpeg_type == JPEG_MJPB));
   72 
   73 /* This information must be stored in the initialization routine because of */
   74 /* direct copy rendering.  Quicktime for Windows must have this information. */
   75         if(codec->jpeg_type == JPEG_MJPA && 
   76             !vtrack->track->mdia.minf.stbl.stsd.table[0].fields)
   77         {
   78             vtrack->track->mdia.minf.stbl.stsd.table[0].fields = 2;
   79             vtrack->track->mdia.minf.stbl.stsd.table[0].field_dominance = 1;
   80         }
   81         codec->initialized = 1;
   82     }
   83 }
   84 
   85 static int decode(quicktime_t *file, 
   86     unsigned char **row_pointers, 
   87     int track)
   88 {
   89     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
   90     initialize(vtrack);
   91     quicktime_jpeg_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
   92     quicktime_trak_t *trak = vtrack->track;
   93     mjpeg_t *mjpeg = codec->mjpeg;
   94     long size, field2_offset = 0;
   95     int track_height = trak->tkhd.track_height;
   96     int track_width = trak->tkhd.track_width;
   97     int result = 0;
   98     int field_dominance = trak->mdia.minf.stbl.stsd.table[0].field_dominance;
   99 
  100     mjpeg_set_cpus(codec->mjpeg, file->cpus);
  101     if(file->row_span) 
  102         mjpeg_set_rowspan(codec->mjpeg, file->row_span);
  103     else
  104         mjpeg_set_rowspan(codec->mjpeg, 0);
  105 
  106     quicktime_set_video_position(file, vtrack->current_position, track);
  107     size = quicktime_frame_size(file, vtrack->current_position, track);
  108     codec->buffer_size = size;
  109 
  110     if(size > codec->buffer_allocated)
  111     {
  112         codec->buffer_allocated = size;
  113         codec->buffer = realloc(codec->buffer, codec->buffer_allocated);
  114     }
  115 
  116     result = !quicktime_read_data(file, codec->buffer, size);
  117 /*
  118  * printf("decode 1 %02x %02x %02x %02x %02x %02x %02x %02x\n", 
  119  * codec->buffer[0],
  120  * codec->buffer[1],
  121  * codec->buffer[2],
  122  * codec->buffer[3],
  123  * codec->buffer[4],
  124  * codec->buffer[5],
  125  * codec->buffer[6],
  126  * codec->buffer[7]
  127  * );
  128  */
  129 
  130     if(!result)
  131     {
  132         if(mjpeg_get_fields(mjpeg) == 2)
  133         {
  134             if(file->use_avi)
  135             {
  136                 field2_offset = mjpeg_get_avi_field2(codec->buffer, 
  137                     size, 
  138                     &field_dominance);
  139             }
  140             else
  141             {
  142                 field2_offset = mjpeg_get_quicktime_field2(codec->buffer, 
  143                     size);
  144 // Sanity check
  145                 if(!field2_offset)
  146                 {
  147                     printf("decode: FYI field2_offset=0\n");
  148                     field2_offset = mjpeg_get_field2(codec->buffer, size);
  149                 }
  150             }
  151         }
  152         else
  153             field2_offset = 0;
  154 
  155 
  156 //printf("decode 2 %d\n", field2_offset);
  157 /*
  158  * printf("decode result=%d field1=%llx field2=%llx size=%d %02x %02x %02x %02x\n", 
  159  * result, 
  160  * quicktime_position(file) - size,
  161  * quicktime_position(file) - size + field2_offset,
  162  * size,
  163  * codec->buffer[0], 
  164  * codec->buffer[1], 
  165  * codec->buffer[field2_offset + 0], 
  166  * codec->buffer[field2_offset + 1]);
  167  */
  168 
  169         if(file->in_x == 0 && 
  170             file->in_y == 0 && 
  171             file->in_w == track_width &&
  172             file->in_h == track_height &&
  173             file->out_w == track_width &&
  174             file->out_h == track_height)
  175         {
  176             int i;
  177             mjpeg_decompress(codec->mjpeg, 
  178                 codec->buffer, 
  179                 size,
  180                 field2_offset,  
  181                 row_pointers, 
  182                 row_pointers[0], 
  183                 row_pointers[1], 
  184                 row_pointers[2],
  185                 file->color_model,
  186                 file->cpus);
  187         }
  188         else
  189         {
  190             int i;
  191             unsigned char **temp_rows;
  192             int temp_cmodel = BC_YUV888;
  193             int temp_rowsize = cmodel_calculate_pixelsize(temp_cmodel) * track_width;
  194 
  195             if(!codec->temp_video)
  196                 codec->temp_video = malloc(temp_rowsize * track_height);
  197             temp_rows = malloc(sizeof(unsigned char*) * track_height);
  198             for(i = 0; i < track_height; i++)
  199                 temp_rows[i] = codec->temp_video + i * temp_rowsize;
  200 
  201 //printf("decode 10\n");
  202             mjpeg_decompress(codec->mjpeg, 
  203                 codec->buffer, 
  204                 size,
  205                 field2_offset,  
  206                 temp_rows, 
  207                 temp_rows[0], 
  208                 temp_rows[1], 
  209                 temp_rows[2],
  210                 temp_cmodel,
  211                 file->cpus);
  212 
  213             cmodel_transfer(row_pointers, 
  214                 temp_rows,
  215                 row_pointers[0],
  216                 row_pointers[1],
  217                 row_pointers[2],
  218                 temp_rows[0],
  219                 temp_rows[1],
  220                 temp_rows[2],
  221                 file->in_x, 
  222                 file->in_y, 
  223                 file->in_w, 
  224                 file->in_h,
  225                 0, 
  226                 0, 
  227                 file->out_w, 
  228                 file->out_h,
  229                 temp_cmodel, 
  230                 file->color_model,
  231                 0,
  232                 track_width,
  233                 file->out_w);
  234 
  235 //printf("decode 30\n");
  236             free(temp_rows);
  237 
  238 //printf("decode 40\n");
  239         }
  240     }
  241 //printf("decode 2 %d\n", result);
  242 
  243     return result;
  244 }
  245 
  246 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
  247 {
  248     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  249     initialize(vtrack);
  250     quicktime_jpeg_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  251     quicktime_trak_t *trak = vtrack->track;
  252     mjpeg_set_quality(codec->mjpeg, codec->quality);
  253     mjpeg_set_float(codec->mjpeg, codec->use_float);
  254     int64_t offset = quicktime_position(file);
  255     int result = 0;
  256     long field2_offset;
  257     quicktime_atom_t chunk_atom;
  258 
  259 //printf("encode 1\n");
  260     mjpeg_set_cpus(codec->mjpeg, file->cpus);
  261 
  262     mjpeg_compress(codec->mjpeg, 
  263         row_pointers, 
  264         row_pointers[0], 
  265         row_pointers[1], 
  266         row_pointers[2],
  267         file->color_model,
  268         file->cpus);
  269     if(codec->jpeg_type == JPEG_MJPA)
  270     {
  271         if(file->use_avi)
  272         {
  273             mjpeg_insert_avi_markers(&codec->mjpeg->output_data,
  274                 &codec->mjpeg->output_size,
  275                 &codec->mjpeg->output_allocated,
  276                 2,
  277                 &field2_offset);
  278         }
  279         else
  280         {
  281             mjpeg_insert_quicktime_markers(&codec->mjpeg->output_data,
  282                 &codec->mjpeg->output_size,
  283                 &codec->mjpeg->output_allocated,
  284                 2,
  285                 &field2_offset);
  286         }
  287     }
  288 
  289     quicktime_write_chunk_header(file, trak, &chunk_atom);
  290     result = !quicktime_write_data(file, 
  291                 mjpeg_output_buffer(codec->mjpeg), 
  292                 mjpeg_output_size(codec->mjpeg));
  293     quicktime_write_chunk_footer(file, 
  294                     trak,
  295                     vtrack->current_chunk,
  296                     &chunk_atom, 
  297                     1);
  298 
  299     vtrack->current_chunk++;
  300 //printf("encode 100\n");
  301     return result;
  302 }
  303 
  304 static int reads_colormodel(quicktime_t *file, 
  305         int colormodel, 
  306         int track)
  307 {
  308     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  309     quicktime_jpeg_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  310 
  311 // Some JPEG_PROGRESSIVE is BC_YUV422P
  312     if(codec->jpeg_type == JPEG_PROGRESSIVE)
  313     {
  314         return (colormodel == BC_RGB888 ||
  315             colormodel == BC_YUV888 ||
  316             colormodel == BC_YUV420P ||
  317             colormodel == BC_YUV422P ||
  318             colormodel == BC_YUV422);
  319     }
  320     else
  321     {
  322         return (colormodel == BC_RGB888 ||
  323             colormodel == BC_YUV888 ||
  324 //          colormodel == BC_YUV420P ||
  325             colormodel == BC_YUV422P ||
  326             colormodel == BC_YUV422);
  327 // The BC_YUV420P option was provided only for mpeg2movie use.because some 
  328 // interlaced movies were accidentally in YUV4:2:0
  329     }
  330 }
  331 
  332 static int writes_colormodel(quicktime_t *file, 
  333         int colormodel, 
  334         int track)
  335 {
  336     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  337     quicktime_jpeg_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
  338 
  339     if(codec->jpeg_type == JPEG_PROGRESSIVE)
  340     {
  341         return (colormodel == BC_RGB888 ||
  342             colormodel == BC_YUV888 ||
  343             colormodel == BC_YUV420P);
  344     }
  345     else
  346     {
  347         return (colormodel == BC_RGB888 ||
  348             colormodel == BC_YUV888 ||
  349             colormodel == BC_YUV422P);
  350     }
  351 }
  352 
  353 static int set_parameter(quicktime_t *file, 
  354         int track, 
  355         char *key, 
  356         void *value)
  357 {
  358     quicktime_jpeg_codec_t *codec = ((quicktime_codec_t*)file->vtracks[track].codec)->priv;
  359     
  360     if(!strcasecmp(key, "jpeg_quality"))
  361     {
  362         codec->quality = *(int*)value;
  363     }
  364     else
  365     if(!strcasecmp(key, "jpeg_usefloat"))
  366     {
  367         codec->use_float = *(int*)value;
  368     }
  369     return 0;
  370 }
  371 
  372 static void init_codec_common(quicktime_video_map_t *vtrack, char *compressor)
  373 {
  374     quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
  375     quicktime_jpeg_codec_t *codec;
  376     int i;
  377 
  378     codec = codec_base->priv = calloc(1, sizeof(quicktime_jpeg_codec_t));
  379     if(quicktime_match_32(compressor, QUICKTIME_JPEG))
  380         codec->jpeg_type = JPEG_PROGRESSIVE;
  381     if(quicktime_match_32(compressor, QUICKTIME_MJPA))
  382         codec->jpeg_type = JPEG_MJPA;
  383     codec->quality = 80;
  384     codec->use_float = 0;
  385 
  386 /* Init public items */
  387     codec_base->delete_vcodec = delete_codec;
  388     codec_base->decode_video = decode;
  389     codec_base->encode_video = encode;
  390     codec_base->decode_audio = 0;
  391     codec_base->encode_audio = 0;
  392     codec_base->reads_colormodel = reads_colormodel;
  393     codec_base->writes_colormodel = writes_colormodel;
  394     codec_base->set_parameter = set_parameter;
  395     codec_base->fourcc = compressor;
  396     codec_base->title = (codec->jpeg_type == JPEG_PROGRESSIVE ? "JPEG Photo" : "Motion JPEG A");
  397     codec_base->desc = codec_base->title;
  398 
  399 }
  400 
  401 void quicktime_init_codec_jpeg(quicktime_video_map_t *vtrack)
  402 {
  403     init_codec_common(vtrack, QUICKTIME_JPEG);
  404 }
  405 
  406 void quicktime_init_codec_mjpa(quicktime_video_map_t *vtrack)
  407 {
  408     init_codec_common(vtrack, QUICKTIME_MJPA);
  409 }
  410 
  411 void quicktime_init_codec_mjpg(quicktime_video_map_t *vtrack)
  412 {
  413     init_codec_common(vtrack, "MJPG");
  414 }
  415 
  416 
  417 
  418 
  419