1 /*
2  *  frameinfo.c
3  *
4  *  Copyright (C) Georg Martius - Feb - 2013
5  *   georg dot martius at web dot de
6  *
7  *  This file is part of vid.stab video stabilization library
8  *
9  *  vid.stab is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License,
11  *  as published by the Free Software Foundation; either version 2, or
12  *  (at your option) any later version.
13  *
14  *  vid.stab is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with GNU Make; see the file COPYING.  If not, write to
21  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  */
24 
25 #include "frameinfo.h"
26 #include "vidstabdefines.h"
27 #include <assert.h>
28 #include <string.h>
29 
vsFrameInfoInit(VSFrameInfo * fi,int width,int height,VSPixelFormat pFormat)30 int vsFrameInfoInit(VSFrameInfo* fi, int width, int height, VSPixelFormat pFormat){
31   fi->pFormat=pFormat;
32   fi->width = width;
33   fi->height = height;
34   fi->planes=3;
35   fi->log2ChromaW = 0;
36   fi->log2ChromaH = 0;
37   fi->bytesPerPixel=1;
38   assert(width%2==0 && height%2==0);
39   switch(pFormat){
40    case PF_GRAY8:
41     fi->planes=1;
42     break;
43    case PF_YUV420P:
44     fi->log2ChromaW = 1;
45     fi->log2ChromaH = 1;
46     break;
47    case PF_YUV422P:
48     fi->log2ChromaW = 1;
49     fi->log2ChromaH = 0;
50     break;
51    case PF_YUV444P:
52     break;
53    case PF_YUV410P:
54     fi->log2ChromaW = 2;
55     fi->log2ChromaH = 2;
56     break;
57    case PF_YUV411P:
58     fi->log2ChromaW = 2;
59     fi->log2ChromaH = 0;
60     break;
61    case PF_YUV440P:
62     fi->log2ChromaW = 0;
63     fi->log2ChromaH = 1;
64     break;
65    case PF_YUVA420P:
66     fi->log2ChromaW = 1;
67     fi->log2ChromaH = 1;
68     fi->planes = 4;
69     break;
70    case PF_RGB24:
71    case PF_BGR24:
72     fi->bytesPerPixel=3;
73     fi->planes = 0;
74     break;
75    case PF_RGBA:
76     fi->bytesPerPixel=4;
77     fi->planes = 0;
78     break;
79    default:
80     fi->pFormat=0;
81     return 0;
82   }
83   return 1;
84 }
85 
vsGetPlaneWidthSubS(const VSFrameInfo * fi,int plane)86 int vsGetPlaneWidthSubS(const VSFrameInfo* fi, int plane){
87   return plane == 1 || plane == 2 ? fi->log2ChromaW : 0;
88 }
89 
vsGetPlaneHeightSubS(const VSFrameInfo * fi,int plane)90 int vsGetPlaneHeightSubS(const VSFrameInfo* fi, int plane){
91   return  plane == 1 || plane == 2 ? fi->log2ChromaH : 0;
92 }
93 
vsFrameIsNull(const VSFrame * frame)94 int vsFrameIsNull(const VSFrame* frame) {
95   return frame==0 || frame->data[0]==0;
96 }
97 
98 
vsFramesEqual(const VSFrame * frame1,const VSFrame * frame2)99 int vsFramesEqual(const VSFrame* frame1,const VSFrame* frame2){
100   return frame1 && frame2 && (frame1==frame2 || frame1->data[0] == frame2->data[0]);
101 }
102 
vsFrameNull(VSFrame * frame)103 void vsFrameNull(VSFrame* frame){
104   memset(frame->data,0,sizeof(uint8_t*)*4);
105   memset(frame->linesize,0,sizeof(int)*4);
106 }
107 
vsFrameAllocate(VSFrame * frame,const VSFrameInfo * fi)108 void vsFrameAllocate(VSFrame* frame, const VSFrameInfo* fi){
109   vsFrameNull(frame);
110   if(fi->pFormat<PF_PACKED){
111     int i;
112     assert(fi->planes > 0 && fi->planes <= 4);
113     for (i=0; i< fi->planes; i++){
114       int w = fi->width  >> vsGetPlaneWidthSubS(fi, i);
115       int h = fi->height >> vsGetPlaneHeightSubS(fi, i);
116       frame->data[i] = vs_zalloc(w * h * sizeof(uint8_t));
117       frame->linesize[i] = w;
118       if(frame->data[i]==0)
119         vs_log_error("vid.stab","out of memory: cannot allocated buffer");
120     }
121   }else{
122     assert(fi->planes==1);
123     int w = fi->width;
124     int h = fi->height;
125     frame->data[0] = vs_zalloc(w * h * sizeof(uint8_t)*fi->bytesPerPixel);
126     frame->linesize[0] = w * fi->bytesPerPixel;
127     if(frame->data[0]==0)
128       vs_log_error("vid.stab","out of memory: cannot allocated buffer");
129   }
130 }
131 
vsFrameCopyPlane(VSFrame * dest,const VSFrame * src,const VSFrameInfo * fi,int plane)132 void vsFrameCopyPlane(VSFrame* dest, const VSFrame* src,
133                     const VSFrameInfo* fi, int plane){
134   assert(src->data[plane]);
135   int h = fi->height >> vsGetPlaneHeightSubS(fi, plane);
136   if(src->linesize[plane] == dest->linesize[plane])
137     memcpy(dest->data[plane], src->data[plane], src->linesize[plane] *  h * sizeof(uint8_t));
138   else {
139     uint8_t* d = dest->data[plane];
140     const uint8_t* s = src->data[plane];
141     int w = fi->width  >> vsGetPlaneWidthSubS(fi, plane);
142     for (; h>0; h--) {
143       memcpy(d,s,sizeof(uint8_t) * w);
144       d += dest->linesize[plane];
145       s += src ->linesize[plane];
146     }
147   }
148 }
149 
vsFrameCopy(VSFrame * dest,const VSFrame * src,const VSFrameInfo * fi)150 void vsFrameCopy(VSFrame* dest, const VSFrame* src, const VSFrameInfo* fi){
151   int plane;
152   assert(fi->planes > 0 && fi->planes <= 4);
153   for (plane=0; plane< fi->planes; plane++){
154     vsFrameCopyPlane(dest,src,fi,plane);
155   }
156 }
157 
vsFrameFillFromBuffer(VSFrame * frame,uint8_t * img,const VSFrameInfo * fi)158 void vsFrameFillFromBuffer(VSFrame* frame, uint8_t* img, const VSFrameInfo* fi){
159   assert(fi->planes > 0 && fi->planes <= 4);
160   vsFrameNull(frame);
161   long int offset = 0;
162   int i;
163   for (i=0; i< fi->planes; i++){
164     int w = fi->width  >> vsGetPlaneWidthSubS(fi, i);
165     int h = fi->height >> vsGetPlaneHeightSubS(fi, i);
166     frame->data[i] = img + offset;
167     frame->linesize[i] = w*fi->bytesPerPixel;
168     offset += h * w*fi->bytesPerPixel;
169   }
170 }
171 
vsFrameFree(VSFrame * frame)172 void vsFrameFree(VSFrame* frame){
173   int plane;
174   for (plane=0; plane< 4; plane++){
175     if(frame->data[plane]) vs_free(frame->data[plane]);
176     frame->data[plane]=0;
177     frame->linesize[plane]=0;
178   }
179 }
180 
181 
182 /*
183  * Local variables:
184  *   c-file-style: "stroustrup"
185  *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
186  *   indent-tabs-mode: nil
187  *   c-basic-offset: 2 t
188  * End:
189  *
190  * vim: expandtab shiftwidth=2:
191  */
192