diff options
author | Krow Savcik <krow@savcik.xyz> | 2024-07-31 13:35:43 +0300 |
---|---|---|
committer | Krow Savcik <krow@savcik.xyz> | 2024-07-31 13:35:43 +0300 |
commit | 35fdfc1eb9be244e37002380de6c3ac650648cab (patch) | |
tree | 5475e2dd495c3fc5b1d1861893175b88a42f3de2 /src | |
parent | 1c1c5fa9b1094e96e6eea8abc163949e2277e151 (diff) |
Diffstat (limited to 'src')
-rw-r--r-- | src/canvas.c | 38 | ||||
-rw-r--r-- | src/canvas.h | 3 | ||||
-rw-r--r-- | src/export.c | 124 | ||||
-rw-r--r-- | src/user.c | 2 |
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; +} @@ -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"); |