lqt_color.c

来自「这个库实现了录象功能」· C语言 代码 · 共 1,099 行 · 第 1/3 页

C
1,099
字号
/******************************************************************************* lqt_color.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#include "quicktime/colormodels.h"#include <stdlib.h>#include <string.h>#define LOG_DOMAIN "color"typedef struct  {  char * name;  int colormodel;  } lqt_colormodel_tab;static lqt_colormodel_tab colormodel_table[] =  {    { "Compressed",                BC_COMPRESSED },    { "16 bpp RGB 565",            BC_RGB565 },    { "16 bpp BGR 565",            BC_BGR565 },    { "24 bpp BGR",                BC_BGR888 },    { "32 bpp BGR",                BC_BGR8888 },    { "24 bpp RGB",                BC_RGB888 },    { "32 bpp RGBA",               BC_RGBA8888 },    { "48 bpp RGB",                BC_RGB161616  },     { "64 bpp RGBA",               BC_RGBA16161616  },    { "32 bpp YUVA",               BC_YUVA8888  },       { "YUV 4:2:2 packed (YUY2)",   BC_YUV422  },    { "YUV 4:2:0 planar",          BC_YUV420P },    { "YUV 4:2:2 planar",          BC_YUV422P },    { "YUV 4:4:4 planar",          BC_YUV444P },    { "YUV 4:2:2 planar (16 bit)", BC_YUV422P16 },    { "YUV 4:4:4 planar (16 bit)", BC_YUV444P16 },    { "YUV 4:2:0 planar (jpeg)",   BC_YUVJ420P },    { "YUV 4:2:2 planar (jpeg)",   BC_YUVJ422P },    { "YUV 4:4:4 planar (jpeg)",   BC_YUVJ444P },    { "YUV 4:1:1 planar",          BC_YUV411P },    { "Undefined",                 LQT_COLORMODEL_NONE }  };/* Some functions to find out, how cheap a colorspace conversion can be */int lqt_colormodel_is_yuv(int colormodel)  {  switch(colormodel)    {    case BC_YUVA8888:    case BC_YUV422:    case BC_YUV420P:    case BC_YUV422P:    case BC_YUV444P:    case BC_YUV422P16:    case BC_YUV444P16:    case BC_YUVJ420P:    case BC_YUVJ422P:    case BC_YUVJ444P:    case BC_YUV411P:      return 1;    default:      return 0;    }  }int lqt_colormodel_is_rgb(int colormodel)  {  switch(colormodel)    {    case BC_RGB565:    case BC_BGR565:    case BC_BGR888:    case BC_BGR8888:    case BC_RGB888:    case BC_RGBA8888:    case BC_RGB161616:    case BC_RGBA16161616:      return 1;    default:      return 0;    }  }int lqt_colormodel_has_alpha(int colormodel)  {  switch(colormodel)    {    case BC_RGBA8888:    case BC_RGBA16161616:    case BC_YUVA8888:         return 1;    default:      return 0;    }  }int lqt_colormodel_is_planar(int colormodel)  {  switch(colormodel)    {    case BC_YUV420P:    case BC_YUV422P:    case BC_YUV444P:    case BC_YUV422P16:    case BC_YUV444P16:    case BC_YUVJ422P:    case BC_YUVJ444P:    case BC_YUVJ420P:    case BC_YUV411P:      return 1;    default:      return 0;    }    }/* Get chroma subsampling factors */void lqt_colormodel_get_chroma_sub(int colormodel, int * sub_h, int * sub_v)  {  switch(colormodel)    {    case BC_YUV420P:    case BC_YUVJ420P:      *sub_h = 2;      *sub_v = 2;      break;    case BC_YUV422:    case BC_YUV422P:    case BC_YUVJ422P:    case BC_YUV422P16:      *sub_h = 2;      *sub_v = 1;      break;    case BC_YUV411P:      *sub_h = 4;      *sub_v = 1;      break;    default:      *sub_h = 1;      *sub_v = 1;      break;    }  }/* *   Return the bits of a colormodel. This is used only internally *   and returns the sum of the bits of all components. Downsampling isn't *   taken into account here, YUV 420 has 24 bits. We need to test this, *   because e.g. RGBA8888 -> RGBA16161616 cost extra. */static int colormodel_get_bits(int colormodel)  {  switch(colormodel)    {    case BC_RGB565:    case BC_BGR565:      return 16;    case BC_BGR888:    case BC_BGR8888:    case BC_RGB888:    case BC_YUV422:    case BC_YUV420P:    case BC_YUV422P:    case BC_YUV444P:    case BC_YUVJ420P:    case BC_YUVJ422P:    case BC_YUVJ444P:    case BC_YUV411P:      return 24;    case BC_RGBA8888:    case BC_YUVA8888:         return 32;    case BC_RGB161616:     case BC_YUV422P16:    case BC_YUV444P16:      return 48;    case BC_RGBA16161616:      return 64;    default:      lqt_log(NULL, LQT_LOG_WARNING, LOG_DOMAIN,              "Unknown colormodel (%d)\n",colormodel);      return 0;    }  }/* *  Get the "Price" of a colormodel conversion */static int get_conversion_price(int in_colormodel, int out_colormodel)  {  int input_is_rgb  = lqt_colormodel_is_rgb(in_colormodel);  int output_is_rgb = lqt_colormodel_is_rgb(out_colormodel);    int input_is_yuv  = lqt_colormodel_is_yuv(in_colormodel);  int output_is_yuv = lqt_colormodel_is_yuv(out_colormodel);  int input_has_alpha  = lqt_colormodel_has_alpha(in_colormodel);  int output_has_alpha = lqt_colormodel_has_alpha(out_colormodel);   /* Zero conversions are for free :-) */    if(in_colormodel == out_colormodel)    return 0;  /*   *  Don't know what to do here. It can happen for very few   *  colormodels which aren't supported by any codecs.   */    if(!input_is_rgb && !input_is_yuv)    {    lqt_log(NULL, LQT_LOG_WARNING, LOG_DOMAIN,            "Input colorspace is neither RGB nor YUV, can't predict conversion price");    return 7;    }    if(!output_is_rgb && !output_is_yuv)    {    lqt_log(NULL, LQT_LOG_WARNING, LOG_DOMAIN,            "Output colorspace is neither RGB nor YUV, can't predict conversion price");    return 7;    }  /*   *  Adding or removing the alpha channel means losing information or   *  adding unneccesary information -> too bad   */  if(input_has_alpha != output_has_alpha)    return 6;    /*   *  YUV <-> RGB conversion costs 4-5   */    if((input_is_yuv && output_is_rgb) ||     (input_is_rgb && output_is_yuv))    {    /* Added check to make sure that staying on the same bit depth       is considered as "better" when doing a colorspace conversion. */    if(colormodel_get_bits(in_colormodel) !=      colormodel_get_bits(out_colormodel))      /* With bit conversion: 5   */      return 5;    else       /* No bit conversion is better: 4   */      return 4;    }    /*   *  Alpha blending is a bit more simple   */  if((input_is_yuv && output_is_rgb) ||     (input_is_rgb && output_is_yuv))    return 3;    /* Bit with conversion costs 2   */    if(colormodel_get_bits(in_colormodel) !=     colormodel_get_bits(out_colormodel))    return 2;  /* Reordering of components is cheapest */    return 1;  }int lqt_get_decoder_colormodel(quicktime_t * file, int track)  {  return file->vtracks[track].stream_cmodel;  }static intlqt_get_best_colormodel_decode(quicktime_t * file, int track, int * supported)  {  int ret = LQT_COLORMODEL_NONE;  int index;  int best_conversion_price;  int conversion_price;    int decoder_colormodel = LQT_COLORMODEL_NONE;  decoder_colormodel = lqt_get_decoder_colormodel(file, track);    /* Check, if the decoder colormodel is directly supported */  if(decoder_colormodel != LQT_COLORMODEL_NONE)    {    index = 0;    while(supported[index] != LQT_COLORMODEL_NONE)      {      if(decoder_colormodel == supported[index])        {        ret = supported[index];        break;        }      else        index++;      }    }  else    ret = BC_RGB888;    if(ret == LQT_COLORMODEL_NONE)    {    index = 0;    best_conversion_price = 10;    while(supported[index] != LQT_COLORMODEL_NONE)      {      if(quicktime_reads_cmodel(file, supported[index], track))        {        conversion_price          = get_conversion_price(decoder_colormodel, supported[index]);        if(conversion_price < best_conversion_price)          {          best_conversion_price = conversion_price;          ret = supported[index];          }        }      index++;      }    }  if(ret == LQT_COLORMODEL_NONE)    ret = BC_RGB888;  return ret;  }static intlqt_get_best_colormodel_encode(quicktime_t * file, int track,                               int * supported)  {  int index_supported;  int conversion_price = 0, best_conversion_price = 10;  int ret = LQT_COLORMODEL_NONE;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?