2 #include <caml/alloc.h>
3 #include <caml/memory.h>
5 /* Following is just a rehash of the code in here:
6 http://playstation2-linux.com/download/p2lsd/sparkys_swizzle_code.html
8 static void unswizzle_32_to_8 (void *dst
, unsigned char *src
, void *pal
, int w
, int h
)
16 for (y
= 0; y
< height
; ++y
) {
17 for (x
= 0; x
< w
; ++x
) {
18 int block_location
= (y
&(~0xf))*width
+ (x
&(~0xf))*2;
19 int swap_selector
= (((y
+2)>>2)&0x1)*4;
20 int posY
= (((y
&(~3))>>1) + (y
&1))&0x7;
21 int column_location
= posY
*width
*2 + ((x
+swap_selector
)&0x7)*4;
22 int byte_num
= ((y
>>1)&1) + ((x
>>2)&2);
23 *rgba
++ = palD
[src
[block_location
+ column_location
+ byte_num
]];
28 static void unswizzle_32_to_4 (void *dst
, unsigned char *src
, void *pal
, int w
, int h
)
36 for (y
=0; y
<height
; y
++) {
37 for (x
=0; x
<width
; x
++) {
38 int pageX
= x
& (~0x7f);
39 int pageY
= y
& (~0x7f);
41 int pages_horz
= (width
+127)/128;
42 int pages_vert
= (height
+127)/128;
44 int page_number
= (pageY
/128)*pages_horz
+ (pageX
/128);
46 int page32Y
= (page_number
/pages_vert
)*32;
47 int page32X
= (page_number
%pages_vert
)*64;
49 int page_location
= page32Y
*height
*2 + page32X
*4;
54 int block_location
= ((locX
&(~0x1f))>>1)*height
+ (locY
&(~0xf))*2;
55 int swap_selector
= (((y
+2)>>2)&0x1)*4;
56 int posY
= (((y
&(~3))>>1) + (y
&1))&0x7;
58 int column_location
= posY
*height
*2 + ((x
+swap_selector
)&0x7)*4;
60 int byte_num
= (x
>>3)&3; /* 0,1,2,3 */
61 int bits_set
= (y
>>1)&1; /* 0,1 (lower/upper 4 bits) */
64 src
[page_location
+ block_location
+ column_location
+ byte_num
];
66 /* bits_set = !bits_set; */
67 v
= (v
>> (bits_set
* 4)) & 0x0f;
73 CAMLprim value
ml_to_rgba (value data_v
, value positions_v
,
74 value dim_v
, value type_v
)
76 CAMLparam4 (data_v
, positions_v
, dim_v
, type_v
);
79 char *data
= String_val (data_v
);
80 int pix_pos
= Int_val (Field (positions_v
, 0));
81 int pal_pos
= Int_val (Field (positions_v
, 1));
82 int w
= Int_val (Field (dim_v
, 0));
83 int h
= Int_val (Field (dim_v
, 1));
86 uint32
*pal
= (uint32
*) (data
+ pal_pos
);
87 unsigned char *pix
= (unsigned char *) (data
+ pix_pos
);
89 rgba_v
= caml_alloc_string (size
<< 2);
90 rgba
= (uint32
*) String_val (rgba_v
);
92 switch (Int_val (type_v
)) {
94 for (i
= 0; i
< size
; ++i
)
95 rgba
[i
] = pal
[pix
[i
]];
99 for (i
= 0; i
< (size
>> 1); ++i
) {
100 unsigned char v
= pix
[i
];
101 rgba
[i
*2] = pal
[v
>> 4];
102 rgba
[i
*2+1] = pal
[v
& 0x0f];
107 unswizzle_32_to_8 (rgba
, pix
, pal
, w
, h
);
111 unswizzle_32_to_4 (rgba
, pix
, pal
, w
, h
);