Build acap too
[qemu-vcap.git] / scale.c
blob3ad6c53a3074db926ce5bc68760e63f4472bfbd2
1 #include <caml/fail.h>
2 #include <caml/alloc.h>
3 #include <caml/memory.h>
5 #include <libswscale/swscale.h>
7 typedef struct {
8 int w, h;
9 int out_w, out_h;
10 int pitch;
11 struct SwsContext *sws;
12 int linesize[3];
13 int offset[3];
14 int outsize;
15 } State;
17 static State glob_state;
19 static void sws_reset (State *s)
21 #ifdef ARCH_BIG_ENDIAN
22 int fmt = PIX_FMT_RGB565BE;
23 #else
24 int fmt = PIX_FMT_RGB565LE;
25 #endif
27 if (s->sws) {
28 sws_freeContext (s->sws);
29 s->sws = NULL;
32 s->sws = sws_getContext (s->w, s->h, fmt,
33 s->out_w, s->out_h, PIX_FMT_YUV420P,
34 SWS_BICUBIC,
35 NULL, NULL, NULL);
36 if (!s->sws)
37 caml_failwith ("sws_getContext failed");
40 static void scale (State *s, uint8_t *in, uint8_t *out)
42 int ret;
43 uint8_t *plane[3];
45 plane[0] = out;
46 plane[1] = plane[0] + s->offset[1];
47 plane[2] = plane[1] + s->offset[2];
49 ret = sws_scale (s->sws, &in, &s->pitch,
50 0, s->h, plane, s->linesize);
51 if (ret != s->out_h)
52 caml_failwith ("sws_scale failed");
55 CAMLprim value ml_scale_reset (value params_v)
57 CAMLparam1 (params_v);
58 State *s = &glob_state;
60 s->w = Int_val (Field (params_v, 0));
61 s->h = Int_val (Field (params_v, 1));
62 s->out_w = Int_val (Field (params_v, 2));
63 s->out_h = Int_val (Field (params_v, 3));
64 s->pitch = Int_val (Field (params_v, 4));
66 s->outsize = s->out_w * s->out_h * 3 / 2;
68 s->linesize[0] = s->out_w;
69 s->linesize[1] = s->out_w / 2;
70 s->linesize[2] = s->out_w / 2;
72 s->offset[0] = 0;
73 s->offset[1] = s->out_w * s->out_h;
74 s->offset[2] = s->offset[1] / 4;
76 sws_reset (s);
78 CAMLreturn (Val_int (s->outsize));
81 CAMLprim value ml_scale (value in_v, value out_v)
83 CAMLparam2 (in_v, out_v);
84 State *s = &glob_state;
86 scale (s, String_val (in_v), String_val (out_v));
87 CAMLreturn (Val_unit);