#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; };