aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/canvas.c38
-rw-r--r--src/canvas.h3
-rw-r--r--src/export.c124
-rw-r--r--src/user.c2
4 files changed, 128 insertions, 39 deletions
diff --git a/src/canvas.c b/src/canvas.c
index 21c9096..b5b3d8d 100644
--- a/src/canvas.c
+++ b/src/canvas.c
@@ -23,7 +23,6 @@ typedef struct Layer Layer;
static uint8 canvas_add_cells(Canvas *, uint);
static uint canvas_fill_bfs(Canvas *, int, int, uint, uint);
-static uint canvas_blend_color(uint, uint);
static void canvas_point_redraw(Canvas *, long int, long int);
static void canvas_set_proj_path(Canvas *, const char *);
static void action_do(Canvas *);
@@ -494,41 +493,6 @@ canvas_save(Canvas *c, const char *path, short int s)
}
uint8
-canvas_export_png(Canvas *c, const char *path, void *ren)
-{
-/* TODO: check path */
- SDL_Surface *surf;
- /* SDL_Texture *tex; */
- SDL_Rect dest;
- int i, j, k, ret = 0;
- dest.x = dest.y = 0;
- dest.w = c->w;
- dest.h = c->h;
-
-
- surf = SDL_CreateRGBSurfaceWithFormat( 0, c->w, c->h, 32, SDL_PIXELFORMAT_RGBA8888);
- ret = ret || (surf == NULL);
-
- SDL_LockSurface(surf);
-
-/* TODO: Assuming bad stuff (pixel size) */
- for (j = 0; j < c->h; j++) {
- for (k = 0; k < c->w; k++) {
- canvas_point_redraw(c, k, j);
- ((unsigned int *)surf->pixels)[COORD(k,j)] = c->pres_pix[COORD(k, j)];
- }
- }
-
- SDL_UnlockSurface(surf);
- ret = ret || (IMG_SavePNG(surf, path) == -1);
- SDL_FreeSurface(surf);
-
- if (ret)
- fprintf(stderr, "%s:%d:canvas_export_png: Error while exporting\n", __FILE__, __LINE__);
- return ret;
-}
-
-uint8
canvas_add_layer(Canvas *c, uint pos)
{
int i, j;
@@ -755,7 +719,7 @@ canvas_fill_bfs(Canvas *c, int x, int y, uint oldcol, uint newcol)
return c->temp_cnt;
}
-static uint
+uint
canvas_blend_color(uint a, uint b)
{
/* TODO: do actual blending */
diff --git a/src/canvas.h b/src/canvas.h
index dbda7cf..060887c 100644
--- a/src/canvas.h
+++ b/src/canvas.h
@@ -61,6 +61,7 @@ void canvas_refresh(Canvas *);
void canvas_change_layer(Canvas *, unsigned int);
void canvas_change_frame(Canvas *, unsigned int);
unsigned char canvas_save(Canvas *, const char *, short int);
-unsigned char canvas_export_png(Canvas *, const char *, void *);
+unsigned char canvas_export_png(Canvas *, const char *);
void action_undo(Canvas *);
void action_redo(Canvas *);
+unsigned int canvas_blend_color(unsigned int, unsigned int);
diff --git a/src/export.c b/src/export.c
new file mode 100644
index 0000000..381a240
--- /dev/null
+++ b/src/export.c
@@ -0,0 +1,124 @@
+#include <png.h>
+
+#include "types.h"
+#include "action.h"
+#include "canvas.h"
+#include "debug.h"
+
+#define COORD(x,y) ((x) + (y) * c->w)
+
+uint8
+canvas_export_png(Canvas *c, const char *path)
+{
+ /* TODO: use a defer */
+ uint xcnt, ycnt, cnt, w, h, i, j, k, l, col;
+ FILE *file;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ uint *data, **row_ptr;
+
+ if (c == NULL)
+ return 1;
+
+ if (c->layer_arr_cnt == 0 || c->frame_arr_cnt == 0)
+ return 1;
+
+ file = fopen(path, "wb");
+ if (!file)
+ return 1;
+
+ cnt = xcnt = ycnt = 0;
+
+ for (i = 0; i < c->frame_arr_cnt; i++) {
+ cnt++;
+ if (c->frames[i].state || i+1 == c->frame_arr_cnt) {
+ ++ycnt;
+ xcnt = (cnt > xcnt) ? cnt : xcnt;
+ cnt = 0;
+ }
+ }
+ w = xcnt * c->w;
+ h = ycnt * c->h;
+
+ data = malloc(h*w*sizeof *data);
+ if (data == NULL) {
+ fclose(file);
+ return 1;
+ }
+ row_ptr = malloc(h*sizeof *row_ptr);
+ if (row_ptr == NULL) {
+ fclose(file);
+ free(data);
+ return 1;
+ }
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr) {
+ fclose(file);
+ free(data);
+ free(row_ptr);
+ return 1;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_write_struct(&png_ptr, NULL);
+ fclose(file);
+ free(data);
+ free(row_ptr);
+ return 1;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ fclose(file);
+ free(data);
+ free(row_ptr);
+ return 1;
+ }
+
+ png_init_io(png_ptr, file);
+ png_set_IHDR(png_ptr, info_ptr, w, h,
+ 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+/* png_set_invert_alpha(png_ptr);*/
+ png_write_info(png_ptr, info_ptr);
+/* png_set_swap(png_ptr);*/
+
+ for (i = 0; i < w * h; i++)
+ data[i] = 0;
+
+ for (i = 0; i < h; i++)
+ row_ptr[i] = &data[i * w];
+
+ ycnt = cnt = 0;
+ for (i = 0; i < c->frame_arr_cnt; i++) {
+ for (k = 0; k < c->h; k++) {
+ for (j = 0; j < c->w; j++) {
+ col = 0;
+ for (l = 0; l < c->layer_arr_cnt; l++)
+ if (c->layers[l].visible)
+ col = canvas_blend_color(col,
+ c->cells[c->layer_arr_cnt * i + l][COORD(j, k)]);
+ data[(ycnt * c->h + k) * w + cnt * c->w + j] =
+ ((col&255)<<24) | (((col>>8)&255)<<16) | (((col>>16)&255)<<8) | (((col>>24)&255));
+ }
+ }
+
+ if (c->frames[i].state || i+1 == c->frame_arr_cnt) {
+ ++ycnt;
+ cnt = 0;
+ } else {
+ cnt++;
+ }
+ }
+
+ png_write_image(png_ptr, row_ptr);
+ png_write_end(png_ptr, info_ptr);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ fclose(file);
+ free(data);
+ free(row_ptr);
+
+ return 0;
+}
diff --git a/src/user.c b/src/user.c
index 7469708..daa3e5d 100644
--- a/src/user.c
+++ b/src/user.c
@@ -94,7 +94,7 @@ user_canvas_export_png(const Arg *x)
choose_file_path("Image File Name (export): ", line);
/* TODO: show error window */
- if (canvas_export_png(cur_canvas, line, ren))
+ if (canvas_export_png(cur_canvas, line))
puts("Error while saving file");
else
puts("File saved");