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