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