You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
5.9 KiB
235 lines
5.9 KiB
|
|
#include "vidoiltank.h"
|
|
|
|
#define copypixel(_DEST_, _SRC_) *(_DEST_ + 0) = *(_SRC_ + 0); \
|
|
*(_DEST_ + 1) = *(_SRC_ + 1); \
|
|
*(_DEST_ + 2) = *(_SRC_ + 2);
|
|
|
|
ImageRaw *image_alloc (int w, int h) {
|
|
ImageRaw *i = NULL;
|
|
|
|
i = (ImageRaw *) malloc (sizeof (ImageRaw));
|
|
i->size = w*h*3;
|
|
i->data = malloc(i->size);
|
|
i->w = w;
|
|
i->h = h;
|
|
|
|
return i;
|
|
};
|
|
|
|
|
|
void image_resize(ImageRaw *i, int w, int h) {
|
|
if (i == NULL) {
|
|
printf ("error: image_resize .. image points to NULL\n");
|
|
exit (1);
|
|
}
|
|
|
|
free (i->data);
|
|
i->size = w*h*3;
|
|
i->data = malloc(i->size);
|
|
i->w = w;
|
|
i->h = h;
|
|
};
|
|
|
|
|
|
int image_save(ImageRaw *i, char *fn, int quality) {
|
|
struct jpeg_compress_struct cinfo;
|
|
struct jpeg_error_mgr jerr;
|
|
FILE * outfile; /* target file */
|
|
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
|
|
int row_stride; /* physical row width in image buffer */
|
|
|
|
if (i == NULL) {
|
|
printf ("image_save no image i == NULL\n");
|
|
exit (1);
|
|
}
|
|
|
|
cinfo.err = jpeg_std_error(&jerr);
|
|
jpeg_create_compress(&cinfo);
|
|
|
|
if ((outfile = fopen(fn, "wb")) == NULL) {
|
|
fprintf(stderr, "can't open %s\n", fn);
|
|
exit(1);
|
|
}
|
|
jpeg_stdio_dest(&cinfo, outfile);
|
|
|
|
cinfo.image_width = i->w; /* image width and height, in pixels */
|
|
cinfo.image_height = i->h;
|
|
cinfo.input_components = 3; /* # of color components per pixel */
|
|
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
|
|
jpeg_set_defaults(&cinfo);
|
|
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
|
|
jpeg_start_compress(&cinfo, TRUE);
|
|
row_stride = i->w * 3; /* JSAMPLEs per row in image_buffer */
|
|
|
|
while (cinfo.next_scanline < cinfo.image_height) {
|
|
row_pointer[0] = & i->data[cinfo.next_scanline * row_stride];
|
|
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
|
}
|
|
|
|
jpeg_finish_compress(&cinfo);
|
|
fclose(outfile);
|
|
jpeg_destroy_compress(&cinfo);
|
|
|
|
return 0;
|
|
};
|
|
|
|
void image_rotate (ImageRaw *img, int deg) {
|
|
if (img == NULL || img->data == NULL) return;
|
|
if (deg == 0) return;
|
|
|
|
if (deg == 90 || deg == 270) {
|
|
int nx, ny, x, y;
|
|
int nw = img->h;
|
|
int nh = img->w;
|
|
unsigned char *old = img->data;
|
|
unsigned char *new = malloc (3 * img->w * img->h);
|
|
|
|
for (y = 0; y < img->h; y++) for (x = 0; x < img->w; x++) {
|
|
if (deg == 90) {
|
|
nx = img->h - y -1;
|
|
ny = x;
|
|
}
|
|
else {
|
|
nx = y;
|
|
ny = img->w - x - 1;
|
|
}
|
|
copypixel(new+3*(nx + ny * nw), old+3*(x + y * img->w));
|
|
}
|
|
|
|
img->w = nw;
|
|
img->h = nh;
|
|
img->data = new;
|
|
free (old);
|
|
}
|
|
else if (deg == 180) {
|
|
int x, y, nx, ny;
|
|
unsigned char pixel[3];
|
|
for (y = 0; y < (img->h/2); y++) for (x = 0; x < img->w; x++) {
|
|
nx = img->w - x - 1;
|
|
ny = img->h - y - 1;
|
|
copypixel(pixel, img->data+3*(nx + ny * img->w));
|
|
copypixel(img->data+3*(nx + ny * img->w), img->data+3*(x + y * img->w));
|
|
copypixel(img->data+3*(x + y * img->w), pixel);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
void image_draw_pixel (ImageRaw *img, int x, int y, int col) {
|
|
if (img == NULL || img->data == NULL) return;
|
|
if (x < 0 || x >= img->w) return;
|
|
if (y < 0 || y >= img->h) return;
|
|
|
|
memcpy (img->data+3*(x+y*img->w), &col, 3);
|
|
}
|
|
|
|
|
|
void image_draw_rect (ImageRaw *img, Rect *r, int col) {
|
|
if (r == NULL || img == NULL || img->data == NULL) return;
|
|
if (r->x + r->w > img->w || r->y + r->h > img->h) return;
|
|
int x, y;
|
|
|
|
for (x = 0; x < r->w && x + r->x < img->w; x++) {
|
|
image_draw_pixel (img, x, r->y, col);
|
|
image_draw_pixel (img, x, r->y+r->h-1, col);
|
|
}
|
|
for (y = 0; y < r->h && y + r->y < img->h; y++) {
|
|
image_draw_pixel (img, r->x, y, col);
|
|
image_draw_pixel (img, r->x + r->w - 1, y, col);
|
|
}
|
|
}
|
|
|
|
|
|
void image_get_minmax (ImageRaw *img, Rect *r, int *min, int *max) {
|
|
int x, y, l, cr, cg, cb;
|
|
if (img == NULL || img->data == NULL) return;
|
|
|
|
cr = (unsigned char)*(img->data+0+3*(r->x+r->y*img->w));
|
|
cg = (unsigned char)*(img->data+1+3*(r->x+r->y*img->w));
|
|
cb = (unsigned char)*(img->data+2+3*(r->x+r->y*img->w));
|
|
*min = *max = cr + cg + cb;
|
|
|
|
for (x = r->x; x < (r->x+r->w) && x < img->w; x++)
|
|
for (y = r->y; y < (r->w + r->h) && y < img->h; y++) {
|
|
cr = (unsigned char)*(img->data+0+3*(x+y*img->w));
|
|
cg = (unsigned char)*(img->data+1+3*(x+y*img->w));
|
|
cb = (unsigned char)*(img->data+2+3*(x+y*img->w));
|
|
// printf ("%d %d %d\n", cr, cg, cb);
|
|
l = cr + cg + cb;
|
|
if (l < *min) *min = l;
|
|
if (l > *max) *max = l;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ImageFloat *imageF_alloc (int w, int h) {
|
|
ImageFloat *i = NULL;
|
|
|
|
i = (ImageFloat *) malloc (sizeof (ImageFloat));
|
|
i->size = w*h*sizeof(float);
|
|
i->data = (float *)malloc(i->size);
|
|
i->w = w;
|
|
i->h = h;
|
|
|
|
return i;
|
|
};
|
|
|
|
|
|
ImageFloat *imageF_copy(ImageRaw *iraw, Rect *r) {
|
|
ImageFloat *ifloat = imageF_alloc(r->w, r->h);
|
|
int x, y;
|
|
float f;
|
|
|
|
for (y = 0; y < r->h; y++) for (x = 0; x < r->w; x++) {
|
|
f = *(iraw->data+0+3*(r->x + x + (r->y + y)*iraw->w)) +
|
|
*(iraw->data+1+3*(r->x + x + (r->y + y)*iraw->w)) +
|
|
*(iraw->data+2+3*(r->x + x + (r->y + y)*iraw->w));
|
|
f = f/3.0;
|
|
*(ifloat->data+(x+y*ifloat->w)) = f;
|
|
}
|
|
|
|
return ifloat;
|
|
};
|
|
|
|
void imageF_add(ImageFloat *ifloat, ImageRaw *iraw, Rect *r) {
|
|
int x, y;
|
|
float f;
|
|
|
|
for (y = 0; y < r->h; y++) for (x = 0; x < r->w; x++) {
|
|
f = *(iraw->data+0+3*(r->x + x + (r->y + y)*iraw->w)) +
|
|
*(iraw->data+1+3*(r->x + x + (r->y + y)*iraw->w)) +
|
|
*(iraw->data+2+3*(r->x + x + (r->y + y)*iraw->w));
|
|
f = f/3.0;
|
|
*(ifloat->data+(x+y*ifloat->w)) += f;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
ImageRaw *image_copyF(ImageFloat *ifloat) {
|
|
ImageRaw *iraw = image_alloc(ifloat->w, ifloat->h);
|
|
int x, y;
|
|
int min, max;
|
|
unsigned char c;
|
|
|
|
// get limit
|
|
min = max = *(ifloat->data);
|
|
for (y = 0; y < ifloat->h; y++) for (x = 0; x < ifloat->w; x++) {
|
|
if (*(ifloat->data+(x+y*ifloat->w)) < min)
|
|
min = *(ifloat->data+(x+y*ifloat->w));
|
|
if (*(ifloat->data+(x+y*ifloat->w)) > max)
|
|
max = *(ifloat->data+(x+y*ifloat->w));
|
|
}
|
|
|
|
for (y = 0; y < ifloat->h; y++) for (x = 0; x < ifloat->w; x++) {
|
|
c = (255.0 * (*(ifloat->data+(x+y*ifloat->w)) - min) / (max - min));
|
|
*(iraw->data+0+3*(x + y * iraw->w)) = c;
|
|
*(iraw->data+1+3*(x + y * iraw->w)) = c;
|
|
*(iraw->data+2+3*(x + y * iraw->w)) = c;
|
|
}
|
|
|
|
return iraw;
|
|
};
|