no clue :) just to push it
[demo] / src / image.cc
1 #include <stdlib.h>
2 #include <string.h>
3
4 #include "imago2.h"
5 #include "image.h"
6
7 Image::Image()
8 {
9         w = h = psz = 0;
10         pixels = 0;
11
12         is_float = false;
13 }
14
15 Image::~Image()
16 {
17         free(pixels);
18 }
19
20 Image::Image(const Image &image)
21 {
22         w = image.w;
23         h = image.h;
24         is_float = image.is_float;
25         psz = image.psz;
26
27         if(!(pixels = malloc(w * h * psz))) {
28                 fprintf(stderr, "Failed to allocate pixels.\n");
29                 abort();
30         }
31         memcpy(pixels, image.pixels, w * h * psz);
32 }
33
34 Image &Image::operator =(const Image &image)
35 {
36         if(&image == this)
37                 return *this;
38
39         free(pixels);
40
41         w = image.w;
42         h = image.h;
43         psz = image.psz;
44         is_float = image.is_float;
45
46         if(!(pixels = malloc(w * h * psz))) {
47                 fprintf(stderr, "Failed to allocate pixels.\n");
48                 abort();
49         }
50         memcpy(pixels, image.pixels, w * h * psz);
51
52         return *this;
53 }
54
55 Image::Image(Image &&image)
56 {
57         w = image.w;
58         h = image.h;
59         psz = image.psz;
60         is_float = image.is_float;
61
62         pixels = image.pixels;
63         image.pixels = 0;
64 }
65
66 Image &Image::operator =(Image &&image)
67 {
68         if(&image == this)
69                 return *this;
70
71         free(pixels);
72
73         w = image.w;
74         h = image.h;
75         psz = image.psz;
76         is_float = image.is_float;
77
78         pixels = image.pixels;
79         image.pixels = 0;
80
81         return *this;
82 }
83
84 bool Image::load(const char *fname)
85 {
86         free(pixels);
87
88         img_pixmap ipm;
89         img_init(&ipm);
90
91         if(img_load(&ipm, fname) == -1) {
92                 fprintf(stderr, "Failed to load image: %s.\n", fname);
93
94                 img_destroy(&ipm);
95                 return false;
96         }
97
98         printf("Successfully loaded image: %s\n", fname);
99
100         img_fmt format = img_is_float(&ipm) ? IMG_FMT_RGBAF : IMG_FMT_RGBA32;
101         if(img_convert(&ipm, format) == -1) {
102                 fprintf(stderr, "Failed to convert image %s.\n", fname);
103
104                 img_destroy(&ipm);
105                 return false;
106         }
107
108         w = ipm.width;
109         h = ipm.height;
110         psz = ipm.pixelsz;
111         is_float = img_is_float(&ipm) ? true : false;
112
113         if(!(pixels = malloc(w * h * psz))) {
114                 fprintf(stderr, "Failed to allocate pixels for image: %s.\n", fname);
115                 return false;
116         }
117
118         memcpy(pixels, ipm.pixels, w * h * psz);
119
120         img_destroy(&ipm);
121         return true;
122 }
123
124 Vec4 Image::get_pixel(int x, int y) const
125 {
126         if(is_float) {
127                 return ((Vec4 *)pixels)[y * w + x];
128         }
129
130         Vec4 color;
131         unsigned char *pptr = ((unsigned char *)pixels) + (y * w + x) * 4;
132         color.x = pptr[0] / 255.0;
133         color.y = pptr[1] / 255.0;
134         color.z = pptr[2] / 255.0;
135         color.w = pptr[3] / 255.0;
136
137         return color;
138 }
139
140 Vec4 Image::lookup_nearest(float u, float v) const
141 {
142         int x = (int)(u * w) % w;
143         int y = (int)(v * h) % h;
144
145         return get_pixel(x, y);
146 }
147
148 Vec4 Image::lookup_linear(float u, float v, float du, float dv) const
149 {
150         /* bottom left */
151         int x0 = (int)(u * w) % w;
152         int y0 = (int)(v * h) % h;
153         int x1 = (x0 + 1) % w;
154         int y1 = (y0 + 1) % h;
155
156         /* uv coordinates at the img corners */
157         float u0 = (float)x0 / (float)w;
158         float v0 = (float)y0 / (float)h;
159         float u1 = (float)(x0 + 1) / (float)w;
160         float v1 = (float)(y0 + 1) / (float)h;
161
162         float tu = (u - u0) / (u1 - u0);
163         float tv = (v - v0) / (v1 - v0);
164
165         Vec4 p00 = get_pixel(x0, y0);
166         Vec4 p01 = get_pixel(x0, y1);
167         Vec4 p11 = get_pixel(x1, y1);
168         Vec4 p10 = get_pixel(x1, y0);
169
170         Vec4 ptop = lerp(p01, p11, tu);
171         Vec4 pbot = lerp(p00, p10, tu);
172
173         return lerp(pbot, ptop, tv);
174 }