2 Copyright © 2011, The AROS Development Team.
6 #include <datatypes/pictureclass.h>
7 #include <libraries/cybergraphics.h>
9 #include <proto/alib.h>
10 #include <proto/datatypes.h>
11 #include <proto/dos.h>
12 #include <proto/graphics.h>
13 #include <proto/exec.h>
14 #include <proto/intuition.h>
15 #include <proto/cybergraphics.h>
19 #include <aros/debug.h>
24 #define GET_A(rgb) (((rgb) >> 24) & 0xff)
26 #define GET_A(rgb) ((rgb) & 0xff)
29 /* Code taken from BM__Hidd_BitMap__BitMapScale */
30 /* srcdata point directly to (0,0) point of subbuffer to be read from */
31 ULONG
* ScaleBuffer(ULONG
* srcdata
, LONG widthBuffer
/* stride */, LONG widthSrc
, LONG heightSrc
, LONG widthDest
, LONG heightDest
)
33 ULONG
* scaleddata
= (ULONG
*) AllocVec(sizeof(ULONG
) * widthDest
* heightDest
, MEMF_ANY
);
35 UWORD
* linepattern
= (UWORD
*) AllocVec(sizeof(UWORD
) * widthDest
, MEMF_ANY
);
39 ULONG dyd
= heightDest
;
40 ULONG dxd
= widthDest
;
44 ULONG dys
= heightSrc
;
45 LONG accuyd
= - (dys
>> 1);
46 LONG accuxd
= - (dxs
>> 1);
48 ULONG
* lastscaledlineptr
= scaleddata
+ ((heightDest
- 1) * widthDest
);
51 while (count
< widthDest
) {
53 while (accuxd
> accuxs
) {
58 linepattern
[count
] = xs
;
64 while (count
< heightDest
) {
66 while (accuyd
> accuys
) {
72 //HIDD_BM_GetImage(msg->src, (UBYTE *) srcbuf, bsa->bsa_SrcWidth * sizeof(ULONG), bsa->bsa_SrcX, bsa->bsa_SrcY + ys, bsa->bsa_SrcWidth, 1, vHidd_StdPixFmt_Native32);
73 ULONG
* srcptr
= srcdata
+ (ys
* widthBuffer
);
76 /* New: use last line as temp buffer */
77 for (x
= 0; x
< widthDest
; x
++)
78 lastscaledlineptr
[x
] = srcptr
[linepattern
[x
]];
82 //HIDD_BM_PutImage(msg->dst, msg->gc, (UBYTE *) dstbuf, bsa->bsa_DestWidth * sizeof(ULONG), bsa->bsa_DestX, bsa->bsa_DestY + count, bsa->bsa_DestWidth, 1, vHidd_StdPixFmt_Native32);
83 CopyMem(lastscaledlineptr
, scaleddata
+ (count
* widthDest
), widthDest
* sizeof(ULONG
));
93 void DisposeImageContainer(struct NewImage
*ni
)
101 DisposeDTObject(ni
->o
);
107 FreeVec(ni
->filename
);
109 FreeVec(ni
->subimageinbm
);
110 FreeBitMap(ni
->bitmap2
);
116 void DisposeLUT8ImageContainer(struct NewLUT8Image
*ni
)
125 struct NewLUT8Image
*NewLUT8ImageContainer(UWORD w
, UWORD h
)
127 struct NewLUT8Image
*ni
;
129 ni
= AllocVec(sizeof(struct NewLUT8Image
), MEMF_ANY
| MEMF_CLEAR
);
134 ni
->data
= AllocVec(w
* h
, MEMF_ANY
| MEMF_CLEAR
);
135 if (ni
->data
== NULL
)
144 struct NewImage
*NewImageContainer(UWORD w
, UWORD h
)
148 ni
= AllocVec(sizeof(struct NewImage
), MEMF_ANY
| MEMF_CLEAR
);
153 ni
->subimagescols
= 1;
154 ni
->subimagesrows
= 1;
155 ni
->data
= AllocVec(w
* h
* sizeof (ULONG
), MEMF_ANY
| MEMF_CLEAR
);
156 if (ni
->data
== NULL
)
165 struct NewImage
*ScaleNewImage(struct NewImage
* oni
, UWORD neww
, UWORD newh
)
169 ni
= AllocVec(sizeof(struct NewImage
), MEMF_ANY
| MEMF_CLEAR
);
174 ni
->subimagescols
= oni
->subimagescols
;
175 ni
->subimagesrows
= oni
->subimagesrows
;
177 ni
->data
= ScaleBuffer(oni
->data
, oni
->w
, oni
->w
, oni
->h
, ni
->w
, ni
->h
);
178 if (ni
->data
== NULL
)
187 struct NewImage
*GetImageFromFile(STRPTR path
, STRPTR name
,
188 ULONG expectedsubimagescols
, ULONG expectedsubimagesrows
)
190 struct BitMapHeader
*bmhd
= NULL
;
191 struct NewImage
*ni
= NULL
;
192 struct BitMap
*map
= NULL
;
193 struct RastPort
*rp
= NULL
;
195 struct pdtBlitPixelArray pa
;
202 len
= strlen(path
) + strlen(name
) + 2;
203 buffer
= AllocVec(len
, MEMF_CLEAR
| MEMF_ANY
);
204 strncpy(buffer
, path
, len
);
205 AddPart(buffer
, name
, len
);
207 pic
= NewDTObject(buffer
, DTA_SourceType
, DTST_FILE
,
208 DTA_GroupID
, GID_PICTURE
,
210 PDTA_DestMode
, PMODE_V43
,
214 GetAttr(PDTA_BitMapHeader
, pic
, (APTR
)&bmhd
);
219 h
= bmhd
->bmh_Height
;
220 mask
= bmhd
->bmh_Masking
;
221 ni
= NewImageContainer(w
, h
);
224 ni
->filename
= AllocVec(len
, MEMF_CLEAR
| MEMF_ANY
);
225 strncpy(ni
->filename
, buffer
, len
);
226 ni
->subimagescols
= expectedsubimagescols
;
227 ni
->subimagesrows
= expectedsubimagesrows
;
228 pa
.MethodID
= PDTM_READPIXELARRAY
;
229 pa
.pbpa_PixelData
= (APTR
) ni
->data
;
230 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
231 pa
.pbpa_PixelArrayMod
= w
*4;
236 DoMethodA(pic
, (Msg
) &pa
);
238 if (bmhd
->bmh_Depth
<= 8)
240 GetAttr(PDTA_BitMap
, pic
, (APTR
)&map
);
241 if (map
&& (mask
== mskHasTransparentColor
))
243 rp
= CreateRastPort();
244 if (rp
) rp
->BitMap
= map
;
251 for (y
= 0; y
< h
; y
++)
253 for (x
= 0; x
< w
; x
++)
256 if (ReadPixel(rp
, x
, y
) == 0) dst
[x
+y
*w
] &= 0xffffff00; else dst
[x
+y
*w
] |= 0x000000ff;
258 if (ReadPixel(rp
, x
, y
) == 0) dst
[x
+y
*w
] &= 0x00ffffff; else dst
[x
+y
*w
] |= 0xff000000;
266 DisposeDTObject(pic
);
274 static Object
* LoadPicture(CONST_STRPTR filename
, struct Screen
*scr
)
278 o
= NewDTObject((APTR
)filename
,
279 DTA_GroupID
, GID_PICTURE
,
280 OBP_Precision
, PRECISION_EXACT
,
281 PDTA_Screen
, (IPTR
)scr
,
282 PDTA_FreeSourceBitMap
, TRUE
,
283 PDTA_DestMode
, PMODE_V43
,
284 PDTA_UseFriendBitMap
, TRUE
,
289 struct FrameInfo fri
= {0};
291 D(bug("DTM_FRAMEBOX\n", o
));
292 DoMethod(o
,DTM_FRAMEBOX
,NULL
,(IPTR
)&fri
,(IPTR
)&fri
,sizeof(struct FrameInfo
),0);
294 if (fri
.fri_Dimensions
.Depth
> 0)
296 D(bug("DTM_PROCLAYOUT\n", o
));
297 if (DoMethod(o
,DTM_PROCLAYOUT
,NULL
,1))
308 /* This function must never return NULL, because logic in drawing code
309 checks img->ok instead of img != NULL to make decisions */
310 struct NewImage
* CreateNewImageContainerMatchingScreen(struct NewImage
*in
, BOOL truecolor
, struct Screen
* scr
)
312 struct NewImage
* out
= AllocVec(sizeof(struct NewImage
), MEMF_ANY
| MEMF_CLEAR
);
319 out
->subimagescols
= in
->subimagescols
;
320 out
->subimagesrows
= in
->subimagesrows
;
321 out
->filename
= NULL
;
326 if (in
->data
!= NULL
)
328 out
->data
= AllocVec(out
->w
* out
->h
* sizeof(ULONG
), MEMF_ANY
| MEMF_CLEAR
);
329 if (out
->data
!= NULL
) CopyMem(in
->data
, out
->data
, out
->w
* out
->h
* sizeof(ULONG
));
331 out
->ok
= (out
->data
!= NULL
) ? TRUE
: FALSE
;
332 /* Allocate decision table, all values are set to FALSE (MEMF_CLEAR) */
333 out
->subimageinbm
= AllocVec(in
->subimagescols
* in
->subimagesrows
* sizeof(BOOL
), MEMF_ANY
| MEMF_CLEAR
);
335 out
->filename
= AllocVec(strlen(in
->filename
) + 5, MEMF_ANY
| MEMF_CLEAR
); /* size + 5 -> covers all */
336 strcpy(out
->filename
, in
->filename
);
340 /* If this is LUT screen, try to load LUT version of image */
342 strcpy(out
->filename
, in
->filename
);
343 strcat(out
->filename
, "_LUT");
345 out
->o
= LoadPicture(out
->filename
, scr
);
348 /* Load the original image with conversion */
349 out
->o
= LoadPicture(in
->filename
, scr
);
351 strcpy(out
->filename
, in
->filename
);
356 GetDTAttrs(out
->o
, PDTA_DestBitMap
, (IPTR
)&out
->bitmap
, TAG_DONE
);
357 if (out
->bitmap
== NULL
)
358 GetDTAttrs(out
->o
, PDTA_BitMap
, (IPTR
)&out
->bitmap
, TAG_DONE
);
360 if (out
->bitmap
!= NULL
)
362 GetDTAttrs(out
->o
, PDTA_MaskPlane
, (IPTR
)&out
->mask
, TAG_DONE
);
367 DisposeDTObject(out
->o
);
373 if (out
->data
!= NULL
)
375 ULONG subimagewidth
= out
->w
/ out
->subimagescols
;
376 ULONG subimageheight
= out
->h
/ out
->subimagesrows
;
377 ULONG col
= 0, row
= 0, x
= 0, y
= 0;
380 BOOL atleastone
= FALSE
;
382 /* It is possible that some subimage do not have alpha channel.
383 If that is true, we could create a bitmap that can be later used
384 for blitting instead of alpha drawing */
386 /* Scan subimages and detect which don't have alpha channel */
387 for (row
= 0; row
< out
->subimagesrows
; row
++)
389 for (col
= 0; col
< out
->subimagescols
; col
++)
391 /* Assume image can be put to bitmap */
392 out
->subimageinbm
[col
+ (row
* out
->subimagescols
)] = TRUE
;
393 /* Place pointer at beginning of subimage */
394 ULONG
* ptr
= out
->data
+ (row
* out
->w
* subimageheight
) + (col
* subimagewidth
);
395 for (y
= 0; y
< subimageheight
; y
++)
397 for (x
= 0; x
< subimagewidth
; x
++)
399 if (GET_A(*ptr
) != 0xFF)
400 out
->subimageinbm
[col
+ (row
* out
->subimagescols
)] = FALSE
;
403 ptr
+= (subimagewidth
* (out
->subimagescols
- 1)); /* Advance to next subimage line */
408 /* Check if there was at least one subimage without alpha channel */
409 D(bug("File: %s : ", out
->filename
));
410 for (row
= 0; row
< out
->subimagesrows
; row
++)
412 for (col
= 0; col
< out
->subimagescols
; col
++)
414 D(bug("sb(%d,%d):", col
, row
));
415 if (out
->subimageinbm
[col
+ (row
* out
->subimagescols
)])
428 /* If yes, generate a bitmap */
431 struct RastPort
* rp
= CreateRastPort();
432 out
->bitmap2
= AllocBitMap(out
->w
, out
->h
, 1, 0, scr
->RastPort
.BitMap
);
433 rp
->BitMap
= out
->bitmap2
;
434 WritePixelArray(out
->data
, 0, 0, out
->w
* 4, rp
, 0, 0, out
->w
, out
->h
, RECTFMT_ARGB
);
443 struct Region
*RegionFromLUT8Image(int w
, int h
, struct NewLUT8Image
*s
)
445 struct Region
*shape
;
447 BOOL transp
, transpstate
;
450 if (s
== NULL
) return NULL
;
452 UBYTE
*src
= s
->data
;
457 struct Rectangle rect
= {0, s
->h
, w
-1, h
-1};
458 if (!OrRectRegion(shape
, &rect
)) failed
= TRUE
;
459 for(y
= 0; y
< s
->h
; y
++)
461 struct Rectangle rect
= {0, y
, 0, y
};
463 for(x
= 0; x
< s
->w
; x
++)
465 transp
= src
[y
* s
->w
+ x
] == 0;
470 rect
.MaxX
= rect
.MinX
= x
;
476 OrRectRegion(shape
, &rect
);
485 if (!transpstate
) if (!OrRectRegion(shape
, &rect
)) failed
= TRUE
;
489 DisposeRegion(shape
);