2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
8 #include <hidd/graphics.h>
9 #include "graphics_intern.h"
12 #include <aros/debug.h>
14 /****************************************************************************************/
16 #warning "Does not yet handle SwapPixelBytes flag of HIDDT_PixelFormat structure!"
18 /****************************************************************************************/
20 #define SHIFT_PIX(pix, shift) \
21 (( (shift) < 0) ? (pix) >> (-shift) : (pix) << (shift) )
24 #define GETPIX32(s, pix) \
25 do { pix = *(ULONG *)s; s = (UBYTE *)s + 4; } while (0)
28 #define GETPIX24(s, pix) \
31 pix = (((UBYTE *)s)[0] << 16) | \
32 (((UBYTE *)s)[1] << 8) | \
38 #define GETPIX24(s, pix) \
41 pix = (((UBYTE *)s)[2] << 16) | \
42 (((UBYTE *)s)[1] << 8) | \
49 #define GETPIX16(s, pix) \
50 do { pix = *(UWORD *)s; s = (UBYTE *)s + 2; } while (0)
51 #define GETPIX16OE(s, pix) \
52 do { pix = AROS_SWAP_BYTES_WORD(*(UWORD *)s); s = (UBYTE *)s + 2; } while (0)
55 #define GETPIX8(s, pix) \
56 do { pix = *(BYTE *)s; s = (UBYTE *)s + 1; } while (0)
58 #define GET_TRUE_PIX(s, pix, pf) \
59 switch ((pf)->bytes_per_pixel) { \
60 case 4: GETPIX32(s, pix); break; \
61 case 3: GETPIX24(s, pix); break; \
62 case 2: if ((pf)->flags & vHidd_PixFmt_SwapPixelBytes_Flag) \
67 default: D(bug("RUBBISH BYTES PER PIXEL IN GET_TRUE_PIX()\n")); break; \
71 #define GET_PAL_PIX(s, pix, pf, lut) \
72 switch (pf->bytes_per_pixel) { \
73 case 4: GETPIX32(s, pix); break; \
74 case 3: GETPIX24(s, pix); break; \
75 case 2: GETPIX16(s, pix); break; \
76 case 1: GETPIX8 (s, pix); break; \
77 default: D(bug("RUBBISH BYTES PER PIXEL IN GET_PAL_PIX()\n")); break; \
81 #define PUTPIX32(d, pix) \
82 do { *(ULONG *)d = pix; d = (UBYTE *)d + 4; } while (0)
85 #define PUTPIX24(d, pix) \
88 ((UBYTE *)d)[0] = (UBYTE)((pix >> 16) & 0x000000FF); \
89 ((UBYTE *)d)[1] = (UBYTE)((pix >> 8 ) & 0x000000FF); \
90 ((UBYTE *)d)[2] = (UBYTE)( pix & 0x000000FF); \
94 #define PUTPIX24(d, pix) \
97 ((UBYTE *)d)[2] = (UBYTE)((pix >> 16) & 0x000000FF); \
98 ((UBYTE *)d)[1] = (UBYTE)((pix >> 8 ) & 0x000000FF); \
99 ((UBYTE *)d)[0] = (UBYTE)( pix & 0x000000FF); \
100 d = (UBYTE *)d + 3; \
105 #define PUTPIX16(d, pix) \
106 do { *(UWORD *)d = pix; d = (UBYTE *)d + 2; } while (0)
108 #define PUTPIX16OE(d, pix) \
109 do { *(UWORD *)d = AROS_SWAP_BYTES_WORD(pix); d = (UBYTE *)d + 2; } while (0)
111 #define PUT_TRUE_PIX(d, pix, pf) \
112 switch (pf->bytes_per_pixel) { \
113 case 4: PUTPIX32(d, pix); break; \
114 case 3: PUTPIX24(d, pix); break; \
115 case 2: if ((pf)->flags & vHidd_PixFmt_SwapPixelBytes_Flag) \
116 PUTPIX16OE(d, pix); \
120 default: D(bug("RUBBISH BYTES PER PIXEL IN PUT_TRUE_PIX()\n")); break; \
127 #define INIT_VARS() \
128 UBYTE *src = *msg->srcPixels; \
129 UBYTE *dst = *msg->dstBuf; \
131 #define INIT_FMTVARS() \
132 HIDDT_PixelFormat *srcfmt = msg->srcPixFmt; \
133 HIDDT_PixelFormat *dstfmt = msg->dstPixFmt;
135 /****************************************************************************************/
137 static VOID
true_to_true(OOP_Class
*cl
, OOP_Object
*o
,
138 struct pHidd_BitMap_ConvertPixels
*msg
)
140 LONG alpha_diff
, red_diff
, green_diff
, blue_diff
;
148 alpha_diff
= srcfmt
->alpha_shift
- dstfmt
->alpha_shift
;
149 red_diff
= srcfmt
->red_shift
- dstfmt
->red_shift
;
150 green_diff
= srcfmt
->green_shift
- dstfmt
->green_shift
;
151 blue_diff
= srcfmt
->blue_shift
- dstfmt
->blue_shift
;
155 bug("true_to_true()\n: src = %x dest = %x srcfmt = %d %d %d %d [%d] destfmt = %d %d %d %d [%d]\n",
156 src
, dst
, srcfmt
->alpha_shift
, srcfmt
->red_shift
, srcfmt
->green_shift
, srcfmt
->blue_shift
, srcfmt
->bytes_per_pixel
,
157 dstfmt
->alpha_shift
, dstfmt
->red_shift
, dstfmt
->green_shift
, dstfmt
->blue_shift
, dstfmt
->bytes_per_pixel
);
159 bug("srcmasks = %p %p %p %p\n",
164 bug("destmasks = %p %p %p %p diffs = %d %d %d %d\n",
174 for (y
= 0; y
< msg
->height
; y
++)
179 for (x
= 0; x
< msg
->width
; x
++)
181 /* Get the source pixel */
182 HIDDT_Pixel srcpix
= 0, dstpix
;
184 GET_TRUE_PIX(s
, srcpix
, srcfmt
);
186 dstpix
= (SHIFT_PIX(srcpix
& srcfmt
->alpha_mask
, alpha_diff
) & dstfmt
->alpha_mask
)
187 | (SHIFT_PIX(srcpix
& srcfmt
->red_mask
, red_diff
) & dstfmt
->red_mask
)
188 | (SHIFT_PIX(srcpix
& srcfmt
->green_mask
, green_diff
) & dstfmt
->green_mask
)
189 | (SHIFT_PIX(srcpix
& srcfmt
->blue_mask
, blue_diff
) & dstfmt
->blue_mask
);
192 bug("[ %p, %p, %p, %p ] "
194 , srcpix
& srcfmt
->blue_mask
195 , SHIFT_PIX(srcpix
& srcfmt
->blue_mask
, blue_diff
)
196 , SHIFT_PIX(srcpix
& srcfmt
->blue_mask
, blue_diff
) & dstfmt
->blue_mask
);
200 // bug("[ %p => %p ] \n", srcpix, dstpix);
201 /* Write the pixel to the destination buffer */
202 PUT_TRUE_PIX(d
, dstpix
, dstfmt
);
211 *msg
->srcPixels
= src
;
215 /****************************************************************************************/
217 static VOID
true_to_pal(OOP_Class
*cl
, OOP_Object
*o
,
218 struct pHidd_BitMap_ConvertPixels
*msg
)
220 D(bug("BitMap::ConvertPixels() : Truecolor to palette conversion not implemented yet\n"));
223 static VOID
pal_to_true(OOP_Class
*cl
, OOP_Object
*o
,
224 struct pHidd_BitMap_ConvertPixels
*msg
)
233 lut
= msg
->pixlut
->pixels
;
235 for (y
= 0; y
< msg
->height
; y
++)
240 for (x
= 0; x
< msg
->width
; x
++)
244 GET_PAL_PIX(s
, srcpix
, srcfmt
, lut
);
246 /* We now have a pixel in Native32 format. Put it back */
247 PUT_TRUE_PIX(d
, srcpix
, dstfmt
);
256 *msg
->srcPixels
= src
;
260 /****************************************************************************************/
262 static VOID
pal_to_pal(OOP_Class
*cl
, OOP_Object
*o
,
263 struct pHidd_BitMap_ConvertPixels
*msg
)
265 HIDDT_PixelFormat
*spf
, *dpf
;
267 spf
= msg
->srcPixFmt
;
268 dpf
= msg
->dstPixFmt
;
271 if ( spf
->clut_shift
== dpf
->clut_shift
272 && spf
->clut_mask
== dpf
->clut_mask
)
274 /* This one is rather easy, just copy the data */
279 /* Convert pixel-by pixel */
286 /****************************************************************************************/
288 static void native32_to_native(OOP_Class
*cl
, OOP_Object
*o
,
289 struct pHidd_BitMap_ConvertPixels
*msg
)
292 HIDDT_PixelFormat
*dstfmt
= msg
->dstPixFmt
;
295 D(bug("SRC: Native32, DST: Native, height=%d, width=%d, bytes per pixel: %d, srcmod: %d, dstmod: %d, depth: %d\n"
296 , msg
->height
, msg
->width
, dstfmt
->bytes_per_pixel
, msg
->srcMod
, msg
->dstMod
, dstfmt
->depth
));
298 for ( y
= 0; y
< msg
->height
; y
++)
303 for (x
= 0; x
< msg
->width
; x
++)
306 switch (dstfmt
->bytes_per_pixel
)
309 *(ULONG
*)d
= (ULONG
)*((HIDDT_Pixel
*)s
);
310 d
+= 4; s
+= sizeof(HIDDT_Pixel
);
317 dstpix
= *((HIDDT_Pixel
*)s
);
319 d
[0] = (UBYTE
)((dstpix
>> 16) & 0x000000FF);
320 d
[1] = (UBYTE
)((dstpix
>> 8) & 0x000000FF);
321 d
[2] = (UBYTE
)(dstpix
& 0x000000FF);
323 d
+= 3; s
+= sizeof(HIDDT_Pixel
);
328 *((UWORD
*)d
) = (UWORD
)(*((HIDDT_Pixel
*)s
));
329 d
+= 2; s
+= sizeof(HIDDT_Pixel
);
333 *d
= (UBYTE
)*((HIDDT_Pixel
*)s
);
334 d
+= 1; s
+= sizeof(HIDDT_Pixel
);
339 if (dstfmt
->depth
== 1)
343 mask
= XCOORD_TO_MASK(x
);
344 d
= ((UBYTE
*)dst
) + XCOORD_TO_BYTEIDX(x
);
345 if (*((HIDDT_Pixel
*)s
) ++) {
346 *((UBYTE
*)d
) |= mask
;
348 *((UBYTE
*)d
) &= ~mask
;
363 *msg
->srcPixels
= src
;
367 /****************************************************************************************/
369 static VOID
quick_copy(OOP_Class
*cl
, OOP_Object
*o
,
370 struct pHidd_BitMap_ConvertPixels
*msg
)
372 /* Just do a simple memcpy() of the pixels */
374 HIDDT_PixelFormat
*srcfmt
= msg
->srcPixFmt
;
375 ULONG bpl
= msg
->width
* srcfmt
->bytes_per_pixel
;
377 #warning This does not work well for formats with bytes_per_pixel < 1
379 if (msg
->srcMod
== bpl
&& msg
->dstMod
== bpl
)
381 memcpy(dst
, src
, bpl
* msg
->height
);
388 copy_width
= msg
->width
* srcfmt
->bytes_per_pixel
;
390 for (i
= 0; i
< msg
->height
; i
++)
392 memcpy(dst
, src
, copy_width
);
398 *msg
->srcPixels
= src
;
403 /****************************************************************************************/
405 #warning Discuss this design decision:
407 /* Should we pass HIDDT_PixelFormat * or HIDDT_StdPixFmt ?
408 The first is more flexible for the user, as he will not only be restricted
409 to standard pixek formats. However the user will have to convert
410 from HIDDT_StdPixFmt to HIDDT_PixelFormat manually.
412 In the latter case this conversion will be done inside the method below.
413 This means that we can call an internal function directly
414 to do the conversion and save two method calls.
417 /****************************************************************************************/
419 VOID
BM__Hidd_BitMap__ConvertPixels(OOP_Class
*cl
, OOP_Object
*o
,
420 struct pHidd_BitMap_ConvertPixels
*msg
)
422 /* For now we assume truecolor */
423 HIDDT_PixelFormat
*srcfmt
, *dstfmt
;
425 //bug("bitmap_convertpixels()\n");
427 srcfmt
= msg
->srcPixFmt
;
428 dstfmt
= msg
->dstPixFmt
;
431 /* bug("ConvertPixels: src=%d, dst=%d\n"
432 , srcfmt->stdpixfmt, dstfmt->stdpixfmt);
435 /* Check if source and dest are the same format */
436 if (srcfmt
->stdpixfmt
== dstfmt
->stdpixfmt
)
438 quick_copy(cl
, o
, msg
);
443 if ( srcfmt
->stdpixfmt
== vHidd_StdPixFmt_Native32
444 && dstfmt
->stdpixfmt
== vHidd_StdPixFmt_Native
)
447 native32_to_native(cl
, o
, msg
);
451 switch (HIDD_PF_COLMODEL(srcfmt
))
453 case vHidd_ColorModel_TrueColor
:
454 switch (HIDD_PF_COLMODEL(dstfmt
))
456 case vHidd_ColorModel_TrueColor
:
457 if ((srcfmt
->stdpixfmt
>= FIRST_RGB_STDPIXFMT
) &&
458 (dstfmt
->stdpixfmt
>= FIRST_RGB_STDPIXFMT
) &&
459 (srcfmt
->stdpixfmt
<= LAST_RGB_STDPIXFMT
) &&
460 (dstfmt
->stdpixfmt
<= LAST_RGB_STDPIXFMT
))
462 HIDDT_RGBConversionFunction f
;
464 ObtainSemaphoreShared(&CSD(cl
)->rgbconvertfuncs_sem
);
466 f
= CSD(cl
)->rgbconvertfuncs
[srcfmt
->stdpixfmt
- FIRST_RGB_STDPIXFMT
]
467 [dstfmt
->stdpixfmt
- FIRST_RGB_STDPIXFMT
];
471 if ((*f
)(*msg
->srcPixels
, msg
->srcMod
, srcfmt
->stdpixfmt
,
472 *msg
->dstBuf
, msg
->dstMod
, dstfmt
->stdpixfmt
,
473 msg
->width
, msg
->height
))
475 *msg
->srcPixels
+= (msg
->srcMod
* msg
->height
);
476 *msg
->dstBuf
+= (msg
->dstMod
* msg
->height
);
478 ReleaseSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
484 ReleaseSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
488 true_to_true(cl
, o
, msg
);
492 case vHidd_ColorModel_Palette
:
493 case vHidd_ColorModel_StaticPalette
:
494 true_to_pal(cl
, o
, msg
);
500 case vHidd_ColorModel_Palette
:
501 case vHidd_ColorModel_StaticPalette
:
502 switch (HIDD_PF_COLMODEL(dstfmt
))
504 case vHidd_ColorModel_TrueColor
:
505 pal_to_true(cl
, o
, msg
);
508 case vHidd_ColorModel_Palette
:
509 case vHidd_ColorModel_StaticPalette
:
510 pal_to_pal(cl
,o
, msg
);
520 /****************************************************************************************/