00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "config.h"
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024
00025 #if HAVE_MALLOC_H
00026 #include <malloc.h>
00027 #endif
00028
00029 #include "img_format.h"
00030 #include "mp_image.h"
00031
00032 #include "libvo/fastmemcpy.h"
00033
00034
00035 void mp_image_alloc_planes(mp_image_t *mpi) {
00036
00037 if (mpi->imgfmt == IMGFMT_IF09) {
00038 mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8+
00039 mpi->chroma_width*mpi->chroma_height);
00040 } else
00041 mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8);
00042 if (mpi->flags&MP_IMGFLAG_PLANAR) {
00043 int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1;
00044
00045 mpi->stride[0]=mpi->stride[3]=bpp*mpi->width;
00046 if(mpi->num_planes > 2){
00047 mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width;
00048 if(mpi->flags&MP_IMGFLAG_SWAPPED){
00049
00050 mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
00051 mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
00052 if (mpi->num_planes > 3)
00053 mpi->planes[3]=mpi->planes[2]+mpi->stride[2]*mpi->chroma_height;
00054 } else {
00055
00056 mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height;
00057 mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height;
00058 if (mpi->num_planes > 3)
00059 mpi->planes[3]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
00060 }
00061 } else {
00062
00063 mpi->stride[1]=mpi->chroma_width;
00064 mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
00065 }
00066 } else {
00067 mpi->stride[0]=mpi->width*mpi->bpp/8;
00068 if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
00069 mpi->planes[1] = av_malloc(1024);
00070 }
00071 mpi->flags|=MP_IMGFLAG_ALLOCATED;
00072 }
00073
00074 mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) {
00075 mp_image_t* mpi = new_mp_image(w,h);
00076
00077 mp_image_setfmt(mpi,fmt);
00078 mp_image_alloc_planes(mpi);
00079
00080 return mpi;
00081 }
00082
00083 void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) {
00084 if(mpi->flags&MP_IMGFLAG_PLANAR){
00085 memcpy_pic(dmpi->planes[0],mpi->planes[0], mpi->w, mpi->h,
00086 dmpi->stride[0],mpi->stride[0]);
00087 memcpy_pic(dmpi->planes[1],mpi->planes[1], mpi->chroma_width, mpi->chroma_height,
00088 dmpi->stride[1],mpi->stride[1]);
00089 memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height,
00090 dmpi->stride[2],mpi->stride[2]);
00091 } else {
00092 memcpy_pic(dmpi->planes[0],mpi->planes[0],
00093 mpi->w*(dmpi->bpp/8), mpi->h,
00094 dmpi->stride[0],mpi->stride[0]);
00095 }
00096 }
00097
00098 void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){
00099 mpi->flags&=~(MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV|MP_IMGFLAG_SWAPPED);
00100 mpi->imgfmt=out_fmt;
00101
00102 if(out_fmt == IMGFMT_MPEGPES ||
00103 out_fmt == IMGFMT_ZRMJPEGNI || out_fmt == IMGFMT_ZRMJPEGIT || out_fmt == IMGFMT_ZRMJPEGIB ||
00104 IMGFMT_IS_HWACCEL(out_fmt)){
00105 mpi->bpp=0;
00106 return;
00107 }
00108 mpi->num_planes=1;
00109 if (IMGFMT_IS_RGB(out_fmt)) {
00110 if (IMGFMT_RGB_DEPTH(out_fmt) < 8 && !(out_fmt&128))
00111 mpi->bpp = IMGFMT_RGB_DEPTH(out_fmt);
00112 else
00113 mpi->bpp=(IMGFMT_RGB_DEPTH(out_fmt)+7)&(~7);
00114 return;
00115 }
00116 if (IMGFMT_IS_BGR(out_fmt)) {
00117 if (IMGFMT_BGR_DEPTH(out_fmt) < 8 && !(out_fmt&128))
00118 mpi->bpp = IMGFMT_BGR_DEPTH(out_fmt);
00119 else
00120 mpi->bpp=(IMGFMT_BGR_DEPTH(out_fmt)+7)&(~7);
00121 mpi->flags|=MP_IMGFLAG_SWAPPED;
00122 return;
00123 }
00124 mpi->flags|=MP_IMGFLAG_YUV;
00125 mpi->num_planes=3;
00126 if (mp_get_chroma_shift(out_fmt, NULL, NULL)) {
00127 mpi->flags|=MP_IMGFLAG_PLANAR;
00128 mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift);
00129 mpi->chroma_width = mpi->width >> mpi->chroma_x_shift;
00130 mpi->chroma_height = mpi->height >> mpi->chroma_y_shift;
00131 }
00132 switch(out_fmt){
00133 case IMGFMT_I420:
00134 case IMGFMT_IYUV:
00135 mpi->flags|=MP_IMGFLAG_SWAPPED;
00136 case IMGFMT_YV12:
00137 return;
00138 case IMGFMT_420A:
00139 case IMGFMT_IF09:
00140 mpi->num_planes=4;
00141 case IMGFMT_YVU9:
00142 case IMGFMT_444P:
00143 case IMGFMT_422P:
00144 case IMGFMT_411P:
00145 case IMGFMT_440P:
00146 case IMGFMT_444P16_LE:
00147 case IMGFMT_444P16_BE:
00148 case IMGFMT_422P16_LE:
00149 case IMGFMT_422P16_BE:
00150 case IMGFMT_420P16_LE:
00151 case IMGFMT_420P16_BE:
00152 return;
00153 case IMGFMT_Y800:
00154 case IMGFMT_Y8:
00155
00156 mpi->flags&=~MP_IMGFLAG_PLANAR;
00157 mpi->num_planes=1;
00158 return;
00159 case IMGFMT_UYVY:
00160 mpi->flags|=MP_IMGFLAG_SWAPPED;
00161 case IMGFMT_YUY2:
00162 mpi->bpp=16;
00163 mpi->num_planes=1;
00164 return;
00165 case IMGFMT_NV12:
00166 mpi->flags|=MP_IMGFLAG_SWAPPED;
00167 case IMGFMT_NV21:
00168 mpi->flags|=MP_IMGFLAG_PLANAR;
00169 mpi->bpp=12;
00170 mpi->num_planes=2;
00171 mpi->chroma_width=(mpi->width>>0);
00172 mpi->chroma_height=(mpi->height>>1);
00173 mpi->chroma_x_shift=0;
00174 mpi->chroma_y_shift=1;
00175 return;
00176 }
00177 mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt);
00178 mpi->bpp=0;
00179 }
00180
00181 mp_image_t* new_mp_image(int w,int h){
00182 mp_image_t* mpi = malloc(sizeof(mp_image_t));
00183 if(!mpi) return NULL;
00184 memset(mpi,0,sizeof(mp_image_t));
00185 mpi->width=mpi->w=w;
00186 mpi->height=mpi->h=h;
00187 return mpi;
00188 }
00189
00190 void free_mp_image(mp_image_t* mpi){
00191 if(!mpi) return;
00192 if(mpi->flags&MP_IMGFLAG_ALLOCATED){
00193
00194 av_free(mpi->planes[0]);
00195 if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
00196 av_free(mpi->planes[1]);
00197 }
00198 free(mpi);
00199 }
00200