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.

229 lines
5.7 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_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;
unsigned char pixel[3];
memcpy (pixel, &col, 3);
for (x = 0; x < r->w; x++) {
copypixel (img->data+3*(r->x+x+(r->y)*img->w), pixel);
copypixel (img->data+3*(r->x+x+(r->y+r->h)*img->w), pixel);
}
for (y = 0; y < r->h; y++) {
copypixel (img->data+3*(r->x+(r->y+y)*img->w), pixel);
copypixel (img->data+3*(r->x+r->w+(r->y+y)*img->w), pixel);
}
}
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;
};