1 /***************************************************************************
2 copyright : (C) 2003-2005 by mean
3 email : fixounet@free.fr
4 ***************************************************************************/
5
6 /***************************************************************************
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 ***************************************************************************/
14
15
16 #include "ADM_default.h"
17 #include "ADM_image.h"
18 /**
19 \fn duplicateMacro
20 \brief copy src to this, swapping u&v possibly
21 */
duplicateMacro(ADMImage * src,bool swap)22 bool ADMImage::duplicateMacro(ADMImage *src,bool swap)
23 {
24 //#warning handle swap
25 // Sanity check
26 ADM_assert(src->_width==_width);
27 ADM_assert(src->_height==_height);
28 ADM_assert(isWrittable()==true); // could not duplicate to a linked data image
29 copyInfo(src);
30 uint32_t sourceStride,destStride;
31 uint8_t *source,*dest;
32
33 hwDecRefCount(); // free hw ref image if any..
34 if(src->refType==ADM_HW_NONE)
35 {
36 for(int plane=PLANAR_Y;plane<PLANAR_LAST;plane++)
37 {
38 source=src->GetReadPtr((ADM_PLANE)plane);
39 dest=this->GetWritePtr((ADM_PLANE)plane);
40 sourceStride=src->GetPitch((ADM_PLANE)plane);
41 destStride=this->GetPitch((ADM_PLANE)plane);
42 int opHeight=_height;
43 int opWidth=_width;
44 if(plane!=PLANAR_Y)
45 {
46 opHeight>>=1;
47 opWidth>>=1;
48 }
49 BitBlit(dest, destStride,source,sourceStride,opWidth, opHeight);
50 }
51 }
52 else // it is a hw surface
53 {
54 refType =src->refType;
55 refDescriptor.refHwImage =src->refDescriptor.refHwImage;
56 refDescriptor.refCodec =src->refDescriptor.refCodec;
57 refDescriptor.refMarkUsed =src->refDescriptor.refMarkUsed;
58 refDescriptor.refMarkUnused=src->refDescriptor.refMarkUnused;
59 refDescriptor.refDownload =src->refDescriptor.refDownload;
60 hwIncRefCount();
61 }
62 return true;
63 }
64 /**
65 \fn duplicate
66 */
duplicate(ADMImage * src)67 bool ADMImage::duplicate(ADMImage *src)
68 {
69 return duplicateMacro(src,false);
70 }
71 /**
72 \fn duplicateFull
73 \brief copy data + info (pts...)
74 */
duplicateFull(ADMImage * src)75 bool ADMImage::duplicateFull(ADMImage *src)
76 {
77 // Sanity check
78 ADM_assert(src->_width==_width);
79 ADM_assert(src->_height==_height);
80
81
82 copyInfo(src);
83 duplicate(src);
84 return 1;
85 }
86 /**
87 \fn copyInfo
88 \brief Copy the additionnal infos attached to an image (flags/aspect ration/PTS)
89 */
copyInfo(ADMImage * src)90 bool ADMImage::copyInfo(ADMImage *src)
91 {
92 _Qp=src->_Qp;
93 flags=src->flags;
94 _aspect=src->_aspect;
95 Pts=src->Pts;
96 return 1;
97 }
98 /**
99 \fn blacken
100 */
blacken(void)101 bool ADMImage::blacken(void)
102 {
103 ADM_assert(isWrittable()==true); // could not duplicate to a linked data image
104 uint32_t sourceStride,destStride;
105 uint8_t *dest;
106
107 for(int plane=PLANAR_Y;plane<PLANAR_LAST;plane++)
108 {
109 dest=this->GetWritePtr((ADM_PLANE)plane);
110 destStride=this->GetPitch((ADM_PLANE)plane);
111 int opHeight=_height;
112 int opWidth=_width;
113 uint8_t color=0;
114 if(plane!=PLANAR_Y)
115 {
116 opHeight>>=1;
117 opWidth>>=1;
118 color=128;
119 }
120 for(int y=0;y<opHeight;y++)
121 {
122 memset(dest,color,opWidth);
123 dest+=destStride;
124 }
125 }
126 return true;
127 }
128 /**
129 \fn copyTo
130 \brief Copy "this" image into dest image at x,y position
131
132 */
copyTo(ADMImage * dest,uint32_t x,uint32_t y)133 bool ADMImage::copyTo(ADMImage *dest, uint32_t x,uint32_t y)
134 {
135
136 uint32_t box_w=_width, box_h=_height;
137 // Clip if needed
138 if(y>dest->_height)
139 {
140 printf("Y out : %u %u\n",y,dest->_height);
141 return 1;
142 }
143 if(x>dest->_width)
144 {
145 printf("X out : %u %u\n",x,dest->_width);
146 return 1;
147 }
148
149 if(x+box_w>dest->_width) box_w=dest->_width-x;
150 if(y+box_h>dest->_height) box_h=dest->_height-y;
151 // Get Source plane
152 uint8_t *srcPlanes[3];
153 uint8_t *dstPlanes[3];
154 dest->GetWritePlanes(dstPlanes);
155 GetReadPlanes(srcPlanes);
156
157 int srcPitches[3],dstPitches[3];
158 dest->GetPitches(dstPitches);
159 GetPitches(srcPitches);
160 // do y
161 for(int i=0;i<3;i++)
162 {
163 int xx=x;
164 int yy=y;
165 int ww=box_w;
166 int hh=box_h;
167 if(i) {xx/=2;yy/=2;ww/=2;hh/=2;} /// u or v
168 BitBlit(dstPlanes[i]+xx+dstPitches[i]*yy, dstPitches[i],
169 srcPlanes[i],srcPitches[i],
170 ww,hh);
171 }
172 return 1;
173
174 }
175 /**
176 \fn copyToAlpha
177 \brief Copy "this" image into dest image at x,y position using alpha alpha
178 @param alpha alpha value (0--255)
179
180 */
copyToAlpha(ADMImage * dest,uint32_t x,uint32_t y,uint32_t alpha)181 bool ADMImage::copyToAlpha(ADMImage *dest, uint32_t x,uint32_t y,uint32_t alpha)
182 {
183
184 uint32_t box_w=_width, box_h=_height;
185 // Clip if needed
186 if(y>dest->_height)
187 {
188 printf("Y out : %u %u\n",y,dest->_height);
189 return 1;
190 }
191 if(x>dest->_width)
192 {
193 printf("X out : %u %u\n",x,dest->_width);
194 return 1;
195 }
196
197 if(x+box_w>dest->_width) box_w=dest->_width-x;
198 if(y+box_h>dest->_height) box_h=dest->_height-y;
199 // Get Source plane
200 uint8_t *srcPlanes[3];
201 uint8_t *dstPlanes[3];
202 dest->GetWritePlanes(dstPlanes);
203 GetReadPlanes(srcPlanes);
204
205 int srcPitches[3],dstPitches[3];
206 dest->GetPitches(dstPitches);
207 GetPitches(srcPitches);
208 // do y
209 for(int i=0;i<3;i++)
210 {
211 int xx=x;
212 int yy=y;
213 int ww=box_w;
214 int hh=box_h;
215 if(i) {xx/=2;yy/=2;ww/=2;hh/=2;} /// u or v
216 BitBlitAlpha(dstPlanes[i]+xx+dstPitches[i]*yy, dstPitches[i],
217 srcPlanes[i],srcPitches[i],
218 ww,hh,alpha);
219 }
220 return 1;
221 }
222 /**
223 * \fn blitWithAlpha
224 * \brief Blie one plane using transparency from alpha Channel
225 * @param dest
226 * @param x
227 * @param y
228 * @param alpha
229 * @return
230 */
231
blitWithAlpha(uint8_t * dst,uint8_t * src,uint8_t * alpha,int dstStride,int srcStride,int alphaStride,int w,int h,int mul,uint32_t opacity)232 static bool blitWithAlpha(uint8_t *dst, uint8_t *src, uint8_t *alpha, int dstStride, int srcStride, int alphaStride, int w, int h, int mul, uint32_t opacity)
233 {
234 for(int k=0;k<h;k++)
235 {
236 for(int j=0;j<w;j++)
237 {
238 int a=alpha[mul*j];
239 if(opacity<255)
240 {
241 a*=opacity;
242 a>>=8;
243 }
244 uint32_t x=(255-a)*dst[j]+a*src[j];
245 dst[j]=x>>8;
246 }
247 dst+=dstStride;
248 src+=srcStride;
249 alpha+=alphaStride*mul;
250 }
251 return true;
252 }
copyWithAlphaChannel(ADMImage * dest,uint32_t x,uint32_t y,uint32_t opacity)253 bool ADMImage::copyWithAlphaChannel(ADMImage *dest, uint32_t x,uint32_t y,uint32_t opacity)
254 {
255 uint32_t box_w=_width, box_h=_height;
256 // Clip if needed
257 if(y>dest->_height)
258 {
259 ADM_info("Image out of target image height : %d %d\n",y,dest->_height);
260 return true;
261 }
262 if(x>dest->_width)
263 {
264 ADM_info("Image out of target image width %d %d\n",x,dest->_width);
265 return true;
266 }
267
268 if(x+box_w>dest->_width) box_w=dest->_width-x;
269 if(y+box_h>dest->_height) box_h=dest->_height-y;
270 // Get Source plane
271 uint8_t *srcPlanes[3];
272 uint8_t *dstPlanes[3];
273 dest->GetWritePlanes(dstPlanes);
274 GetReadPlanes(srcPlanes);
275
276 int srcPitches[3],dstPitches[3];
277 dest->GetPitches(dstPitches);
278 GetPitches(srcPitches);
279
280 uint8_t *alpha=GetReadPtr(PLANAR_ALPHA);
281 int alphaStride=GetPitch(PLANAR_ALPHA);
282
283 // do U & V
284 for(int i=0;i<3;i++)
285 {
286 int mul=0;
287 if(i) mul++;
288 int xx=x>>mul;
289 int yy=y>>mul;
290 int ww=box_w>>mul;
291 int hh=box_h>>mul;
292 mul++;
293 blitWithAlpha( dstPlanes[i]+xx+dstPitches[i]*yy,
294 srcPlanes[i],
295 alpha,
296
297 dstPitches[i],
298 srcPitches[i],
299 alphaStride,
300 ww,hh,mul,opacity);
301 }
302 return 1;
303 }
304 //EOF
305