Reorganize build parameters a bit
[dormin.git] / swizzle.c
blob16de8287873260e51bfc966d5ec995d4fda28dd6
1 #include <caml/fail.h>
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
7 */
8 static void unswizzle_32_to_8 (void *dst, unsigned char *src, void *pal, int w, int h)
10 int x, y;
11 int width = w;
12 int height = h;
13 uint32 *rgba = dst;
14 uint32 *palD = pal;
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)
30 int x, y;
31 int width = w;
32 int height = h;
33 uint32 *rgba = dst;
34 uint32 *palD = pal;
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;
51 int locX = x & 0x7f;
52 int locY = y & 0x7f;
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) */
63 unsigned char v =
64 src[page_location + block_location + column_location + byte_num];
66 /* bits_set = !bits_set; */
67 v = (v >> (bits_set * 4)) & 0x0f;
68 *rgba++ = palD[v];
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);
77 CAMLlocal1 (rgba_v);
78 uint32 *rgba;
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));
84 int size = w * h;
85 int i;
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)) {
93 case 0:
94 for (i = 0; i < size; ++i)
95 rgba[i] = pal[pix[i]];
96 break;
98 case 1:
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];
104 break;
106 case 2:
107 unswizzle_32_to_8 (rgba, pix, pal, w, h);
108 break;
110 case 3:
111 unswizzle_32_to_4 (rgba, pix, pal, w, h);
112 break;
115 CAMLreturn (rgba_v);