aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2014-11-20 12:32:01 +0100
committerGerd Hoffmann <kraxel@redhat.com>2017-03-08 11:27:55 +0100
commitf2c664a04fa6cf49b3719a0cc4c59f57bab04948 (patch)
treef0f9fe151dcb2260b953d3bc840bae6b3796a1a6
parentf897a5ee212491ea5d0560eeb1ca4f6bcfbfe111 (diff)
downloadfbida-f2c664a04fa6cf49b3719a0cc4c59f57bab04948.tar.gz
use pixman images for storage
-rw-r--r--GNUmakefile6
-rw-r--r--color.c2
-rw-r--r--fbi.c34
-rw-r--r--filebutton.c28
-rw-r--r--filter.c24
-rw-r--r--genthumbnail.c21
-rw-r--r--lut.c2
-rw-r--r--op.c27
-rw-r--r--rd/read-xwd.c7
-rw-r--r--readers.c27
-rw-r--r--readers.h7
-rw-r--r--selections.c20
-rw-r--r--viewer.c59
-rw-r--r--wr/write-jpeg.c6
-rw-r--r--wr/write-png.c2
-rw-r--r--wr/write-ppm.c5
-rw-r--r--wr/write-ps.c4
-rw-r--r--wr/write-tiff.c2
18 files changed, 146 insertions, 137 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 732420d..3bc022f 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -12,9 +12,9 @@ CFLAGS += -Wno-pointer-sign
# hard build deps
PKG_CONFIG = pkg-config
-PKGS_IDA := libexif libpng libtiff-4
-PKGS_FBI := freetype2 fontconfig libdrm libexif libpng libtiff-4
-PKGS_FBPDF := libdrm poppler-glib gbm egl epoxy
+PKGS_IDA := libexif libpng libtiff-4 pixman-1
+PKGS_FBI := freetype2 fontconfig libdrm libexif libpng libtiff-4 pixman-1
+PKGS_FBPDF := libdrm poppler-glib gbm egl epoxy pixman-1
HAVE_DEPS := $(shell $(PKG_CONFIG) $(PKGS_FBI) $(PKGS_FBPDF) && echo yes)
# map pkg-config names to debian packages using apt-file
diff --git a/color.c b/color.c
index 510b16d..35a3713 100644
--- a/color.c
+++ b/color.c
@@ -70,7 +70,7 @@ color_calchist(struct ida_image *img, struct ida_coledit *me)
unsigned char *pix;
unsigned int i,x,y,max;
- pix = img->data;
+ pix = (void*)pixman_image_get_data(img->p);
for (y = 0; y < img->i.height; y++) {
for (x = 0; x < img->i.width; x++) {
me->red.data[pix[0]]++;
diff --git a/fbi.c b/fbi.c
index 6965ecb..cfe5f96 100644
--- a/fbi.c
+++ b/fbi.c
@@ -131,7 +131,6 @@ static FT_Face face;
/* fwd declarations */
static struct ida_image *flist_img_get(struct flist *f);
-static void *flist_malloc(size_t size);
static void flist_img_load(struct flist *f, int prefetch);
/* ---------------------------------------------------------------------- */
@@ -348,10 +347,10 @@ shadow_draw_image(struct ida_image *img, int xoff, int yoff,
continue;
if (100 == weight)
shadow_draw_rgbdata(xs, ys+y, dwidth,
- img->data + data + offset);
+ ida_image_scanline(img, y) + offset);
else
shadow_merge_rgbdata(xs, ys+y, dwidth, weight,
- img->data + data + offset);
+ ida_image_scanline(img, y) + offset);
}
}
@@ -541,9 +540,9 @@ static void show_help(void)
static void free_image(struct ida_image *img)
{
if (img) {
- if (img->data) {
+ if (img->p) {
img_mem -= img->i.width * img->i.height * 3;
- free(img->data);
+ ida_image_free(img);
}
free(img);
}
@@ -614,11 +613,11 @@ read_image(char *filename)
free_image(img);
return NULL;
}
- img->data = flist_malloc(img->i.width * img->i.height * 3);
+ ida_image_alloc(img);
img_mem += img->i.width * img->i.height * 3;
for (y = 0; y < img->i.height; y++) {
check_console_switch();
- loader->read(img->data + img->i.width * 3 * y, y, data);
+ loader->read(ida_image_scanline(img, y), y, data);
}
loader->done(data);
return img;
@@ -647,13 +646,11 @@ scale_image(struct ida_image *src, float scale)
p.height = 1;
data = desc_resize.init(src,&rect,&dest->i,&p);
- dest->data = flist_malloc(dest->i.width * dest->i.height * 3);
+ ida_image_alloc(dest);
img_mem += dest->i.width * dest->i.height * 3;
for (y = 0; y < dest->i.height; y++) {
check_console_switch();
- desc_resize.work(src,&rect,
- dest->data + 3 * dest->i.width * y,
- y, data);
+ desc_resize.work(src, &rect, ida_image_scanline(dest, y), y, data);
}
desc_resize.done(data);
return dest;
@@ -1169,21 +1166,6 @@ static void flist_img_release_memory(void)
return;
}
-static void *flist_malloc(size_t size)
-{
- void *ptr;
-
- for (;;) {
- ptr = malloc(size);
- if (ptr)
- return ptr;
- if (0 != flist_img_free_lru()) {
- status_error("Oops: out of memory, exiting");
- exit(1);
- }
- }
-}
-
static void flist_img_scale(struct flist *f, float scale, int prefetch)
{
char linebuffer[128];
diff --git a/filebutton.c b/filebutton.c
index 4e68df0..2ed2e84 100644
--- a/filebutton.c
+++ b/filebutton.c
@@ -107,13 +107,11 @@ fileinfo_cleanup(struct file_button *file)
}
file->state = 0;
- if (file->wimg.data) {
- free(file->wimg.data);
- file->wimg.data = NULL;
+ if (file->wimg.p) {
+ ida_image_free(&file->wimg);
}
- if (file->simg.data) {
- free(file->simg.data);
- file->simg.data = NULL;
+ if (file->simg.p) {
+ ida_image_free(&file->simg);
}
if (!list_empty(&file->queue)) {
list_del_init(&file->queue);
@@ -218,7 +216,7 @@ fileinfo_loader(XtPointer clientdata)
goto unknown;
}
- file->wimg.data = malloc(file->wimg.i.width * file->wimg.i.height * 3);
+ ida_image_alloc(&file->wimg);
file->state = 1;
file->y = 0;
return FALSE;
@@ -226,8 +224,7 @@ fileinfo_loader(XtPointer clientdata)
case 1:
/* ------------------- loading file -------------------- */
if (file->y < file->wimg.i.height) {
- file->loader->read(file->wimg.data
- + 3 * file->y * file->wimg.i.width,
+ file->loader->read(ida_image_scanline(&file->wimg, file->y),
file->y, file->wdata);
file->y++;
return FALSE;
@@ -253,7 +250,7 @@ fileinfo_loader(XtPointer clientdata)
rect.y1 = 0;
rect.y2 = file->wimg.i.height;
file->wdata = desc_resize.init(&file->wimg,&rect,&file->simg.i,&resize);
- file->simg.data = malloc(file->simg.i.width * file->simg.i.height * 3);
+ ida_image_alloc(&file->simg);
file->state = 2;
file->y = 0;
@@ -262,8 +259,8 @@ fileinfo_loader(XtPointer clientdata)
case 2:
/* ------------------- scaling file -------------------- */
if (file->y < file->simg.i.height) {
- desc_resize.work(&file->wimg,&rect, file->simg.data
- + 3 * file->simg.i.width * file->y,
+ desc_resize.work(&file->wimg,&rect,
+ ida_image_scanline(&file->simg, file->y),
file->y, file->wdata);
file->y++;
return FALSE;
@@ -288,12 +285,13 @@ fileinfo_loader(XtPointer clientdata)
rect.x2 = file->simg.i.width;
rect.y1 = 0;
rect.y2 = file->simg.i.height;
+ memset(&timg, 0, sizeof(timg));
data = desc_resize.init(&file->simg,&rect,&timg.i,&resize);
- timg.data = malloc(timg.i.width * timg.i.height * 3);
+ ida_image_alloc(&timg);
for (file->y = 0; file->y < timg.i.height; file->y++)
desc_resize.work(&file->simg,&rect,
- timg.data + 3 * timg.i.width * file->y,
+ ida_image_scanline(&timg, file->y),
file->y, data);
desc_resize.done(data);
@@ -302,7 +300,7 @@ fileinfo_loader(XtPointer clientdata)
image_to_pixmap(&timg),
image_to_pixmap(&file->simg));
file_set_info(file,info);
- free(timg.data);
+ ida_image_free(&timg);
file->state = 0;
goto next;
diff --git a/filter.c b/filter.c
index 283a1fa..12694e4 100644
--- a/filter.c
+++ b/filter.c
@@ -17,7 +17,7 @@ op_grayscale(struct ida_image *src, struct ida_rect *rect,
unsigned char *scanline;
int i,g;
- scanline = src->data + line * src->i.width * 3;
+ scanline = ida_image_scanline(src, line);
memcpy(dst,scanline,src->i.width * 3);
if (line < rect->y1 || line >= rect->y2)
return;
@@ -84,13 +84,9 @@ op_3x3_calc_line(struct ida_image *src, struct ida_rect *rect,
unsigned char *s1,*s2,*s3;
unsigned int i,left,right;
- s1 = src->data + (line-1) * src->i.width * 3;
- s2 = src->data + line * src->i.width * 3;
- s3 = src->data + (line+1) * src->i.width * 3;
- if (0 == line)
- s1 = src->data + line * src->i.width * 3;
- if (src->i.height-1 == line)
- s3 = src->data + line * src->i.width * 3;
+ s1 = ida_image_scanline(src, (0 == line) ? line : line - 1);
+ s2 = ida_image_scanline(src, line);
+ s3 = ida_image_scanline(src, (src->i.height-1 == line) ? line : line + 1 );
left = rect->x1;
right = rect->x2;
@@ -157,7 +153,7 @@ op_3x3_work(struct ida_image *src, struct ida_rect *rect,
struct op_3x3_handle *h = data;
unsigned char *scanline;
- scanline = src->data + line * src->i.width * 3;
+ scanline = ida_image_scanline(src, line);
memcpy(dst,scanline,src->i.width * 3);
if (line < rect->y1 || line >= rect->y2)
return;
@@ -210,7 +206,7 @@ op_sharpe_work(struct ida_image *src, struct ida_rect *rect,
unsigned char *scanline;
int i;
- scanline = src->data + line * src->i.width * 3;
+ scanline = ida_image_scanline(src, line);
memcpy(dst,scanline,src->i.width * 3);
if (line < rect->y1 || line >= rect->y2)
return;
@@ -289,7 +285,7 @@ op_resize_work(struct ida_image *src, struct ida_rect *rect,
fprintf(stderr,"y: %6.2f%%: %d/%d => %d/%d\n",
weight*100,h->srcrow,src->height,line,h->height);
#endif
- csrcline = src->data + h->srcrow * src->i.width * 3;
+ csrcline = ida_image_scanline(src, h->srcrow);
for (i = 0; i < src->i.width * 3; i++)
h->rowbuf[i] += (float)csrcline[i] * weight;
if (0 == h->inleft) {
@@ -396,10 +392,10 @@ unsigned char* op_rotate_getpixel(struct ida_image *src, struct ida_rect *rect,
sy < rect->y1 || sy >= rect->y2) {
if (dx < rect->x1 || dx >= rect->x2 ||
dy < rect->y1 || dy >= rect->y2)
- return src->data + dy * src->i.width * 3 + dx * 3;
+ return ida_image_scanline(src, dy) + dx * 3;
return black;
}
- return src->data + sy * src->i.width * 3 + sx * 3;
+ return ida_image_scanline(src, sy) + sx * 3;
}
static void
@@ -411,7 +407,7 @@ op_rotate_work(struct ida_image *src, struct ida_rect *rect,
float fx,fy,w;
int x,sx,sy;
- pix = src->data + y * src->i.width * 3;
+ pix = ida_image_scanline(src, y);
memcpy(dst,pix,src->i.width * 3);
if (y < h->calc.y1 || y >= h->calc.y2)
return;
diff --git a/genthumbnail.c b/genthumbnail.c
index 1259125..cef280a 100644
--- a/genthumbnail.c
+++ b/genthumbnail.c
@@ -40,9 +40,9 @@ read_jpeg(char *filename)
free(img);
return NULL;
}
- img->data = malloc(img->i.width * img->i.height * 3);
+ ida_image_alloc(img);
for (y = 0; y < img->i.height; y++)
- jpeg_loader.read(img->data + img->i.width * 3 * y, y, data);
+ jpeg_loader.read(ida_image_scanline(img, y), y, data);
jpeg_loader.done(data);
return img;
}
@@ -77,11 +77,9 @@ scale_thumbnail(struct ida_image *src, int max)
p.height = 1;
data = desc_resize.init(src,&rect,&dest->i,&p);
- dest->data = malloc(dest->i.width * dest->i.height * 3);
+ ida_image_alloc(dest);
for (y = 0; y < dest->i.height; y++)
- desc_resize.work(src,&rect,
- dest->data + 3 * dest->i.width * y,
- y, data);
+ desc_resize.work(src, &rect, ida_image_scanline(dest, y), y, data);
desc_resize.done(data);
return dest;
}
@@ -124,7 +122,6 @@ static int
compress_thumbnail(struct ida_image *img, char *dest, int max)
{
struct thc thc;
- unsigned char *line;
unsigned int i;
memset(&thc,0,sizeof(thc));
@@ -141,8 +138,8 @@ compress_thumbnail(struct ida_image *img, char *dest, int max)
jpeg_set_defaults(&thc.dst);
jpeg_start_compress(&thc.dst, TRUE);
- for (i = 0, line = img->data; i < img->i.height; i++, line += img->i.width*3)
- jpeg_write_scanlines(&thc.dst, &line, 1);
+ for (i = 0; i < img->i.height; i++)
+ jpeg_write_scanlines(&thc.dst, (void*)ida_image_scanline(img, i), 1);
jpeg_finish_compress(&(thc.dst));
jpeg_destroy_compress(&(thc.dst));
@@ -167,7 +164,7 @@ int create_thumbnail(char *filename, unsigned char *dest, int max)
//fprintf(stderr,"scale ");
thumb = scale_thumbnail(img,160);
if (!thumb) {
- free(img->data);
+ ida_image_free(img);
free(img);
fprintf(stderr,"FAILED\n");
return -1;
@@ -177,9 +174,9 @@ int create_thumbnail(char *filename, unsigned char *dest, int max)
size = compress_thumbnail(thumb,dest,max);
/* cleanup */
- free(img->data);
+ ida_image_free(img);
free(img);
- free(thumb->data);
+ ida_image_free(thumb);
free(thumb);
return size;
}
diff --git a/lut.c b/lut.c
index 2901355..eda748b 100644
--- a/lut.c
+++ b/lut.c
@@ -72,7 +72,7 @@ op_map_work(struct ida_image *src, struct ida_rect *rect,
unsigned char *scanline;
int i;
- scanline = src->data + line * src->i.width * 3;
+ scanline = ida_image_scanline(src, line);
memcpy(dst,scanline,src->i.width * 3);
if (line < rect->y1 || line >= rect->y2)
return;
diff --git a/op.c b/op.c
index bb484ce..e9ce52f 100644
--- a/op.c
+++ b/op.c
@@ -18,7 +18,7 @@ op_flip_vert(struct ida_image *src, struct ida_rect *rect,
{
char *scanline;
- scanline = src->data + (src->i.height - line - 1) * src->i.width * 3;
+ scanline = ida_image_scanline(src, src->i.height - line - 1);
memcpy(dst,scanline,src->i.width*3);
}
@@ -29,7 +29,7 @@ op_flip_horz(struct ida_image *src, struct ida_rect *rect,
char *scanline;
unsigned int i;
- scanline = src->data + (line+1) * src->i.width * 3;
+ scanline = ida_image_scanline(src, line+1);
for (i = 0; i < src->i.width; i++) {
scanline -= 3;
dst[0] = scanline[0];
@@ -57,7 +57,7 @@ op_rotate_cw(struct ida_image *src, struct ida_rect *rect,
char *pix;
unsigned int i;
- pix = src->data + src->i.width * src->i.height * 3 + line * 3;
+ pix = ida_image_scanline(src, src->i.height) + line * 3;
for (i = 0; i < src->i.height; i++) {
pix -= src->i.width * 3;
dst[0] = pix[0];
@@ -74,7 +74,7 @@ op_rotate_ccw(struct ida_image *src, struct ida_rect *rect,
char *pix;
unsigned int i;
- pix = src->data + (src->i.width-line-1) * 3;
+ pix = ida_image_scanline(src, 0) + (src->i.width-line-1) * 3;
for (i = 0; i < src->i.height; i++) {
dst[0] = pix[0];
dst[1] = pix[1];
@@ -91,7 +91,7 @@ op_invert(struct ida_image *src, struct ida_rect *rect,
unsigned char *scanline;
int i;
- scanline = src->data + line * src->i.width * 3;
+ scanline = ida_image_scanline(src, line);
memcpy(dst,scanline,src->i.width * 3);
if (line < rect->y1 || line >= rect->y2)
return;
@@ -126,7 +126,7 @@ op_crop_work(struct ida_image *src, struct ida_rect *rect,
unsigned char *scanline;
int i;
- scanline = src->data + (line+rect->y1) * src->i.width * 3 + rect->x1 * 3;
+ scanline = ida_image_scanline(src, line+rect->y1) + rect->x1 * 3;
for (i = rect->x1; i < rect->x2; i++) {
dst[0] = scanline[0];
dst[1] = scanline[1];
@@ -156,17 +156,18 @@ op_autocrop_init(struct ida_image *src, struct ida_rect *unused,
rect.x2 = src->i.width;
rect.y1 = 0;
rect.y2 = src->i.height;
+ memset(&img, 0, sizeof(img));
data = desc_3x3.init(src, &rect, &img.i, &filter);
- img.data = malloc(img.i.width * img.i.height * 3);
+ ida_image_alloc(&img);
for (y = 0; y < (int)img.i.height; y++)
- desc_3x3.work(src, &rect, img.data+3*img.i.width*y, y, data);
+ desc_3x3.work(src, &rect, ida_image_scanline(&img, y), y, data);
desc_3x3.done(data);
limit = 64;
/* y border */
for (y = 0; y < (int)img.i.height; y++) {
- line = img.data + img.i.width*y*3;
+ line = ida_image_scanline(&img, y);
for (x = 0; x < (int)img.i.width; x++)
if (line[3*x+0] > limit ||
line[3*x+1] > limit ||
@@ -177,7 +178,7 @@ op_autocrop_init(struct ida_image *src, struct ida_rect *unused,
}
rect.y1 = y;
for (y = (int)img.i.height-1; y > rect.y1; y--) {
- line = img.data + img.i.width*y*3;
+ line = ida_image_scanline(&img, y);
for (x = 0; x < (int)img.i.width; x++)
if (line[3*x+0] > limit ||
line[3*x+1] > limit ||
@@ -191,7 +192,7 @@ op_autocrop_init(struct ida_image *src, struct ida_rect *unused,
/* x border */
for (x = 0; x < (int)img.i.width; x++) {
for (y = 0; y < (int)img.i.height; y++) {
- line = img.data + (img.i.width*y+x) * 3;
+ line = ida_image_scanline(&img, y) + x * 3;
if (line[0] > limit ||
line[1] > limit ||
line[2] > limit)
@@ -203,7 +204,7 @@ op_autocrop_init(struct ida_image *src, struct ida_rect *unused,
rect.x1 = x;
for (x = (int)img.i.width-1; x > rect.x1; x--) {
for (y = 0; y < (int)img.i.height; y++) {
- line = img.data + (img.i.width*y+x) * 3;
+ line = ida_image_scanline(&img, y) + x * 3;
if (line[0] > limit ||
line[1] > limit ||
line[2] > limit)
@@ -214,7 +215,7 @@ op_autocrop_init(struct ida_image *src, struct ida_rect *unused,
}
rect.x2 = x+1;
- free(img.data);
+ ida_image_free(&img);
if (debug)
fprintf(stderr,"y: %d-%d/%u -- x: %d-%d/%u\n",
rect.y1, rect.y2, img.i.height,
diff --git a/rd/read-xwd.c b/rd/read-xwd.c
index c266624..afaa615 100644
--- a/rd/read-xwd.c
+++ b/rd/read-xwd.c
@@ -344,12 +344,11 @@ parse_ximage(struct ida_image *dest, XImage *src)
memset(dest,0,sizeof(*dest));
dest->i.width = src->width;
dest->i.height = src->height;
- dest->data = malloc(dest->i.width * dest->i.height * 3);
- memset(dest->data,0,dest->i.width * dest->i.height * 3);
-
+ ida_image_alloc(dest);
+
for (y = 0; y < src->height; y++) {
h.row = src->data + y*src->bytes_per_line;
- xwd_parse(dest->data + 3*y*dest->i.width, y, &h);
+ xwd_parse(ida_image_scanline(dest, y), y, &h);
}
free(h.pix);
}
diff --git a/readers.c b/readers.c
index 53cb032..b7da842 100644
--- a/readers.c
+++ b/readers.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
+#include <assert.h>
#include "readers.h"
@@ -126,6 +127,32 @@ int load_free_extras(struct ida_image_info *info)
/* ----------------------------------------------------------------------- */
+void ida_image_alloc(struct ida_image *img)
+{
+ assert(img->p == NULL);
+ img->p = pixman_image_create_bits(PIXMAN_r8g8b8,
+ img->i.width, img->i.height, NULL, 0);
+}
+
+uint8_t *ida_image_scanline(struct ida_image *img, int y)
+{
+ uint8_t *scanline;
+
+ assert(img->p != NULL);
+ scanline = (void*)pixman_image_get_data(img->p);
+ scanline += pixman_image_get_stride(img->p) * y;
+ return scanline;
+}
+
+void ida_image_free(struct ida_image *img)
+{
+ assert(img->p != NULL);
+ pixman_image_unref(img->p);
+ img->p = NULL;
+}
+
+/* ----------------------------------------------------------------------- */
+
LIST_HEAD(loaders);
void load_register(struct ida_loader *loader)
diff --git a/readers.h b/readers.h
index b54e5b6..1ad0e94 100644
--- a/readers.h
+++ b/readers.h
@@ -1,3 +1,4 @@
+#include <pixman.h>
#include "list.h"
enum ida_extype {
@@ -27,7 +28,7 @@ struct ida_image_info {
struct ida_image {
struct ida_image_info i;
- unsigned char *data;
+ pixman_image_t *p;
};
struct ida_rect {
int x1,y1,x2,y2;
@@ -86,6 +87,10 @@ struct ida_extra* load_find_extra(struct ida_image_info *info,
enum ida_extype type);
int load_free_extras(struct ida_image_info *info);
+void ida_image_alloc(struct ida_image *img);
+uint8_t *ida_image_scanline(struct ida_image *img, int y);
+void ida_image_free(struct ida_image *img);
+
/* ----------------------------------------------------------------------- */
/* other */
diff --git a/selections.c b/selections.c
index d09507b..7b16264 100644
--- a/selections.c
+++ b/selections.c
@@ -73,9 +73,10 @@ iconify(Widget widget, struct sel_data *data)
}
/* scale down & create pixmap */
- dst = small.data = malloc(small.i.width * small.i.height * 3);
+ ida_image_alloc(&small);
for (y = 0; y < small.i.height; y++) {
- src = data->img.data + 3 * y * scale * data->img.i.width;
+ src = ida_image_scanline(&data->img, y * scale);
+ dst = ida_image_scanline(&small, y);
for (x = 0; x < small.i.width; x++) {
dst[0] = src[0];
dst[1] = src[1];
@@ -95,7 +96,7 @@ iconify(Widget widget, struct sel_data *data)
XtSetArg(args[n], XmNdepth, depth); n++;
data->icon_widget = XmCreateDragIcon(widget,"dragicon",args,n);
- free(small.data);
+ ida_image_free(&small);
}
static struct sel_data*
@@ -130,8 +131,8 @@ sel_free(Atom selection)
XFreePixmap(dpy,sel->icon_pixmap);
if (sel->pixmap)
XFreePixmap(dpy,sel->pixmap);
- if (sel->img.data)
- free(sel->img.data);
+ if (sel->img.p)
+ ida_image_free(&sel->img);
list_del(&sel->list);
free(sel);
@@ -147,10 +148,8 @@ sel_init(Atom selection)
memset(sel,0,sizeof(*sel));
sel->atom = selection;
- sel->img = ida->img;
- sel->img.data = malloc(ida->img.i.width * ida->img.i.height * 3);
- memcpy(sel->img.data, ida->img.data,
- ida->img.i.width * ida->img.i.height * 3);
+ sel->img.i = ida->img.i;
+ sel->img.p = pixman_image_ref(ida->img.p);
list_add_tail(&sel->list,&selections);
return sel;
@@ -310,7 +309,8 @@ selection_convert(Widget widget, XtPointer ignore, XtPointer call_data)
cdata = XtMalloc(sel->img.i.width * sel->img.i.height * 3 + 32);
n = sprintf(cdata,"P6\n%u %u\n255\n",
sel->img.i.width, sel->img.i.height);
- memcpy(cdata+n, sel->img.data, sel->img.i.width*sel->img.i.height*3);
+ memcpy(cdata+n, pixman_image_get_data(sel->img.p),
+ sel->img.i.width*sel->img.i.height*3);
ccs->value = cdata;
ccs->length = n + sel->img.i.width * sel->img.i.height * 3;
ccs->type = MIME_IMAGE_PPM;
diff --git a/viewer.c b/viewer.c
index 2ace20b..419c361 100644
--- a/viewer.c
+++ b/viewer.c
@@ -55,7 +55,7 @@ Pixmap image_to_pixmap(struct ida_image *img)
ximage = x11_create_ximage(app_shell, img->i.width, img->i.height, &shm);
for (y = 0; y < img->i.height; y++) {
- src = img->data + 3*y*img->i.width;
+ src = ida_image_scanline(img, y);
if (display_type == PSEUDOCOLOR) {
dither_line(src, line, y, img->i.width);
for (x = 0; x < img->i.width; x++)
@@ -219,10 +219,10 @@ viewer_cleanup(struct ida_viewer *ida)
ida->op_work = NULL;
ida->op_done = NULL;
ida->op_data = NULL;
- if (ida->op_src.data) {
- if (ida->undo.data) {
+ if (ida->op_src.p) {
+ if (ida->undo.p) {
fprintf(stderr,"have undo buffer /* shouldn't happen */");
- free(ida->undo.data);
+ ida_image_free(&ida->undo);
}
ida->undo = ida->op_src;
memset(&ida->op_src,0,sizeof(ida->op_src));
@@ -247,7 +247,7 @@ viewer_workproc(XtPointer client_data)
for (ida->line = start; ida->line < end; ida->line++) {
if (ida->load_line > ida->line)
continue;
- scanline = ida->img.data + ida->img.i.width * ida->load_line * 3;
+ scanline = ida_image_scanline(&ida->img, ida->load_line);
ida->load_read(scanline,ida->load_line,ida->load_data);
ida->load_line++;
}
@@ -258,7 +258,7 @@ viewer_workproc(XtPointer client_data)
for (ida->line = start; ida->line < end; ida->line++) {
if (ida->op_line > ida->line)
continue;
- scanline = ida->img.data + ida->img.i.width * ida->op_line * 3;
+ scanline = ida_image_scanline(&ida->img, ida->op_line);
ida->op_work(&ida->op_src,&ida->op_rect,
scanline,ida->op_line,ida->op_data);
ida->op_line++;
@@ -275,7 +275,7 @@ viewer_workproc(XtPointer client_data)
}
} else {
for (ida->line = start; ida->line < end; ida->line++) {
- scanline = ida->img.data + ida->img.i.width * ida->line * 3;
+ scanline = ida_image_scanline(&ida->img, ida->line);
viewer_renderline(ida,scanline);
}
}
@@ -322,7 +322,7 @@ static void viewer_workfinish(struct ida_viewer *ida)
if (ida->load_read) {
for (ida->line = ida->load_line; ida->line < ida->img.i.height;) {
- scanline = ida->img.data + ida->img.i.width * ida->line * 3;
+ scanline = ida_image_scanline(&ida->img, ida->line);
ida->load_read(scanline,ida->load_line,ida->load_data);
ida->line++;
ida->load_line++;
@@ -330,7 +330,7 @@ static void viewer_workfinish(struct ida_viewer *ida)
}
if (ida->op_work && 0 == ida->op_preview) {
for (ida->line = ida->op_line; ida->line < ida->img.i.height;) {
- scanline = ida->img.data + ida->img.i.width * ida->line * 3;
+ scanline = ida_image_scanline(&ida->img, ida->line);
ida->op_work(&ida->op_src,&ida->op_rect,
scanline,ida->op_line,ida->op_data);
ida->line++;
@@ -531,7 +531,7 @@ viewer_mouse(Widget widget, XtPointer client_data,
case POINTER_PICK:
x = viewer_i2s(-ida->zoom,eb->x);
y = viewer_i2s(-ida->zoom,eb->y);
- pix = ida->img.data + ida->img.i.width*y*3 + x*3;
+ pix = ida_image_scanline(&ida->img, y) + x * 3;
ida->pick_cb(x,y,pix,ida->pick_data);
ida->pick_cb = NULL;
ida->pick_data = NULL;
@@ -740,20 +740,21 @@ viewer_start_op(struct ida_viewer *ida, struct ida_op *op, void *parm)
viewer_op_rect(ida);
if (debug)
fprintf(stderr,"viewer_start_op: init %s(%p)\n",op->name,parm);
+ memset(&dst, 0, sizeof(dst));
ida->op_data = op->init(&ida->img,&ida->op_rect,&dst.i,parm);
ptr_idle();
if (NULL == ida->op_data)
return -1;
- dst.data = malloc(dst.i.width * dst.i.height * 3);
+ ida_image_alloc(&dst);
/* prepare background processing */
- if (ida->undo.data) {
- free(ida->undo.data);
+ if (ida->undo.p) {
+ ida_image_free(&ida->undo);
memset(&ida->undo,0,sizeof(ida->undo));
}
- if (ida->op_src.data) {
+ if (ida->op_src.p) {
fprintf(stderr,"have op_src buffer /* shouldn't happen */");
- free(ida->op_src.data);
+ ida_image_free(&ida->op_src);
}
ida->op_src = ida->img;
ida->img = dst;
@@ -777,14 +778,14 @@ viewer_undo(struct ida_viewer *ida)
int resize;
viewer_workfinish(ida);
- if (NULL == ida->undo.data)
+ if (NULL == ida->undo.p)
return -1;
viewer_rubber_off(ida);
memset(&ida->current,0,sizeof(ida->current));
-
+
resize = (ida->undo.i.width != ida->img.i.width ||
ida->undo.i.height != ida->img.i.height);
- free(ida->img.data);
+ ida_image_free(&ida->img);
ida->img = ida->undo;
memset(&ida->undo,0,sizeof(ida->undo));
@@ -849,22 +850,22 @@ viewer_loader_start(struct ida_viewer *ida, struct ida_loader *loader,
viewer_workstop(ida);
viewer_rubber_off(ida);
memset(&ida->current,0,sizeof(ida->current));
- if (ida->undo.data) {
- free(ida->undo.data);
+ if (ida->undo.p) {
+ ida_image_free(&ida->undo);
memset(&ida->undo,0,sizeof(ida->undo));
}
- if (NULL != ida->img.data)
- free(ida->img.data);
+ if (NULL != ida->img.p)
+ ida_image_free(&ida->img);
ida->file = filename;
ida->img.i = info;
- ida->img.data = malloc(ida->img.i.width * ida->img.i.height * 3);
-
+ ida_image_alloc(&ida->img);
+
/* prepare background loading */
ida->load_line = 0;
ida->load_read = loader->read;
ida->load_done = loader->done;
ida->load_data = data;
-
+
viewer_autozoom(ida);
return info.npages;
}
@@ -913,13 +914,13 @@ viewer_setimage(struct ida_viewer *ida, struct ida_image *img, char *name)
viewer_workstop(ida);
viewer_rubber_off(ida);
memset(&ida->current,0,sizeof(ida->current));
- if (ida->undo.data) {
- free(ida->undo.data);
+ if (ida->undo.p) {
+ ida_image_free(&ida->undo);
memset(&ida->undo,0,sizeof(ida->undo));
}
- if (NULL != ida->img.data)
- free(ida->img.data);
+ if (NULL != ida->img.p)
+ ida_image_free(&ida->img);
ida->file = name;
ida->img = *img;
diff --git a/wr/write-jpeg.c b/wr/write-jpeg.c
index 2e39c68..08dade5 100644
--- a/wr/write-jpeg.c
+++ b/wr/write-jpeg.c
@@ -81,9 +81,11 @@ jpeg_write(FILE *fp, struct ida_image *img)
jpeg_set_quality(&cinfo, jpeg_quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
- for (i = 0, line = img->data; i < img->i.height; i++, line += img->i.width*3)
+ for (i = 0; i < img->i.height; i++) {
+ line = ida_image_scanline(img, i);
jpeg_write_scanlines(&cinfo, &line, 1);
-
+ }
+
jpeg_finish_compress(&(cinfo));
jpeg_destroy_compress(&(cinfo));
return 0;
diff --git a/wr/write-png.c b/wr/write-png.c
index c8643a5..34f7bed 100644
--- a/wr/write-png.c
+++ b/wr/write-png.c
@@ -52,7 +52,7 @@ png_write(FILE *fp, struct ida_image *img)
png_set_packing(png_ptr);
for (y = 0; y < img->i.height; y++) {
- row = img->data + y * 3 * img->i.width;
+ row = ida_image_scanline(img, y);
png_write_rows(png_ptr, &row, 1);
}
png_write_end(png_ptr, info_ptr);
diff --git a/wr/write-ppm.c b/wr/write-ppm.c
index 016f0ba..1bb1f53 100644
--- a/wr/write-ppm.c
+++ b/wr/write-ppm.c
@@ -19,13 +19,14 @@ ppm_write(FILE *fp, struct ida_image *img)
"# https://www.kraxel.org/blog/linux/fbida/\n"
"%d %d\n255\n",
img->i.width,img->i.height);
- fwrite(img->data, img->i.height, 3*img->i.width, fp);
+ fwrite(ida_image_scanline(img, 0),
+ img->i.height, 3*img->i.width, fp);
return 0;
}
static struct ida_writer ppm_writer = {
label: "PPM",
- ext: { "ppm", NULL},
+ ext: { "ppm", NULL },
write: ppm_write,
};
diff --git a/wr/write-ps.c b/wr/write-ps.c
index 261a092..b1a2877 100644
--- a/wr/write-ps.c
+++ b/wr/write-ps.c
@@ -436,7 +436,7 @@ ps_write(FILE *fp, struct ida_image *img)
/* image data + ps footer */
if (ps.ori == PORTRAIT) {
- p = img->data;
+ p = ida_image_scanline(img, 0);
for (y = 0; y < img->i.height; y++) {
for (x = 0; x < img->i.width; x++) {
if (0 == (x % 10))
@@ -448,7 +448,7 @@ ps_write(FILE *fp, struct ida_image *img)
}
} else {
for (x = img->i.width-1; x != -1; x--) {
- p = img->data + 3*x;
+ p = ida_image_scanline(img, 0) + 3*x;
for (y = 0; y < img->i.height; y++) {
if (0 == (y % 10))
fprintf(fp,"\n");
diff --git a/wr/write-tiff.c b/wr/write-tiff.c
index 29d0788..a52c5a1 100644
--- a/wr/write-tiff.c
+++ b/wr/write-tiff.c
@@ -42,7 +42,7 @@ tiff_write(FILE *fp, struct ida_image *img)
}
for (y = 0; y < img->i.height; y++) {
- buf = img->data + 3*img->i.width*y;
+ buf = ida_image_scanline(img, y);
TIFFWriteScanline(TiffHndl, buf, y, 0);
}
TIFFClose(TiffHndl);