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