Commit | Line | Data |
---|---|---|
80f575fc DM |
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 | ||
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 | ||
86 | int vsGetPlaneWidthSubS(const VSFrameInfo* fi, int plane){ | |
87 | return plane == 1 || plane == 2 ? fi->log2ChromaW : 0; | |
88 | } | |
89 | ||
90 | int vsGetPlaneHeightSubS(const VSFrameInfo* fi, int plane){ | |
91 | return plane == 1 || plane == 2 ? fi->log2ChromaH : 0; | |
92 | } | |
93 | ||
94 | int vsFrameIsNull(const VSFrame* frame) { | |
95 | return frame==0 || frame->data[0]==0; | |
96 | } | |
97 | ||
98 | ||
99 | int vsFramesEqual(const VSFrame* frame1,const VSFrame* frame2){ | |
100 | return frame1 && frame2 && (frame1==frame2 || frame1->data[0] == frame2->data[0]); | |
101 | } | |
102 | ||
103 | void vsFrameNull(VSFrame* frame){ | |
104 | memset(frame->data,0,sizeof(uint8_t*)*4); | |
105 | memset(frame->linesize,0,sizeof(int)*4); | |
106 | } | |
107 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | */ |