This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git.
The branch, master has been updated via 30a31dc2d764c91837a690112c601e6363db224e (commit) via 7f9e2efe90d7fe60e03bf60ab55f59e110113036 (commit) from 05551ed06488f6e537a0705980630f2d36b47c40 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- http://repo.or.cz/w/gfxprim.git/commit/30a31dc2d764c91837a690112c601e6363db2...
commit 30a31dc2d764c91837a690112c601e6363db224e Author: Cyril Hrubis metan@ucw.cz Date: Fri Nov 4 16:17:06 2011 +0100
Basic JPG writer support.
diff --git a/include/loaders/GP_JPG.h b/include/loaders/GP_JPG.h index fddac6e..db9c51f 100644 --- a/include/loaders/GP_JPG.h +++ b/include/loaders/GP_JPG.h @@ -33,22 +33,28 @@ #include "core/GP_ProgressCallback.h"
/* - * Opens up file and checks signature. Upon successful return the file - * possition would be set to eight bytes (exactly after the PNG signature). + * Opens up file and checks signature. */ GP_RetCode GP_OpenJPG(const char *src_path, FILE **f);
/* - * Reads PNG from an open FILE. Expects the file possition set after the eight - * bytes PNG signature. + * Reads JPG from an open FILE. Expects the file possition set after the eight + * bytes JPG signature. */ GP_RetCode GP_ReadJPG(FILE *f, GP_Context **res, GP_ProgressCallback *callback);
/* - * Loads a PNG file into GP_Context. The Context is newly allocated. + * Loads a JPG file into GP_Context. The Context is newly allocated. */ GP_RetCode GP_LoadJPG(const char *src_path, GP_Context **res, GP_ProgressCallback *callback);
+/* + * Saves JPG to a file. + */ +GP_RetCode GP_SaveJPG(const char *dst_path, const GP_Context *src, + GP_ProgressCallback *callback); + + #endif /* LOADERS_GP_JPG_H */ diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c index be0b67c..cbb5758 100644 --- a/libs/loaders/GP_JPG.c +++ b/libs/loaders/GP_JPG.c @@ -64,7 +64,7 @@ static void my_error_exit(j_common_ptr cinfo) { struct my_jpg_err *my_err = (struct my_jpg_err*) cinfo->err;
- GP_DEBUG(1, "ERROR reading jpeg file"); + GP_DEBUG(1, "ERROR reading/writing jpeg file");
longjmp(my_err->setjmp_buf, 1); } @@ -194,3 +194,93 @@ GP_RetCode GP_LoadJPG(const char *src_path, GP_Context **res,
return GP_ReadJPG(f, res, callback); } + +GP_RetCode GP_SaveJPG(const char *dst_path, const GP_Context *src, + GP_ProgressCallback *callback) +{ + FILE *f; + GP_RetCode ret; + struct jpeg_compress_struct cinfo; + struct my_jpg_err my_err; + + if (src->pixel_type != GP_PIXEL_RGB888 && + src->pixel_type != GP_PIXEL_G8) { + GP_DEBUG(1, "Can't save png with pixel type %s", + GP_PixelTypeName(src->pixel_type)); + return GP_ENOIMPL; + } + + f = fopen(dst_path, "wb"); + + if (f == NULL) { + GP_DEBUG(1, "Failed to open '%s' for writing: %s", + dst_path, strerror(errno)); + return GP_EBADFILE; + } + + if (setjmp(my_err.setjmp_buf)) { + ret = GP_EBADFILE;; + goto err1; + } + + cinfo.err = jpeg_std_error(&my_err.error_mgr); + my_err.error_mgr.error_exit = my_error_exit; + + jpeg_create_compress(&cinfo); + + jpeg_stdio_dest(&cinfo, f); + + cinfo.image_width = src->w; + cinfo.image_height = src->h; + cinfo.input_components = src->pixel_type == GP_PIXEL_RGB888 ? 3 : 1; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults(&cinfo); + + jpeg_start_compress(&cinfo, TRUE); + + while (cinfo.next_scanline < cinfo.image_height) { + uint32_t y = cinfo.next_scanline; + + if (src->pixel_type == GP_PIXEL_RGB888) { + uint32_t i; + uint8_t tmp[3 * src->w]; + + memcpy(tmp, GP_PIXEL_ADDR(src, 0, y), 3 * src->w); + + /* fix the pixels as we want in fact BGR */ + for (i = 0; i < src->w; i++) { + uint8_t *pix = tmp + 3 * i; + GP_SWAP(pix[0], pix[2]); + } + + JSAMPROW row = (void*)tmp; + jpeg_write_scanlines(&cinfo, &row, 1); + } else { + JSAMPROW row = (void*)GP_PIXEL_ADDR(src, 0, y); + jpeg_write_scanlines(&cinfo, &row, 1); + } + + if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) { + GP_DEBUG(1, "Operation aborted"); + ret = GP_EINTR; + goto err1; + } + } + + jpeg_finish_compress(&cinfo); + + if (fclose(f)) { + GP_DEBUG(1, "Failed to close file '%s': %s", + dst_path, strerror(errno)); + return GP_EBADFILE; + } + + return GP_ESUCCESS; +//TODO: is cinfo allocated? +err1: + jpeg_destroy_compress(&cinfo); + fclose(f); + unlink(dst_path); + return ret; +}
http://repo.or.cz/w/gfxprim.git/commit/7f9e2efe90d7fe60e03bf60ab55f59e110113...
commit 7f9e2efe90d7fe60e03bf60ab55f59e110113036 Author: Cyril Hrubis metan@ucw.cz Date: Fri Nov 4 15:10:01 2011 +0100
Basic PNG writer code.
diff --git a/include/loaders/GP_PNG.h b/include/loaders/GP_PNG.h index cfa9438..1b4d9cf 100644 --- a/include/loaders/GP_PNG.h +++ b/include/loaders/GP_PNG.h @@ -51,4 +51,10 @@ GP_RetCode GP_ReadPNG(FILE *f, GP_Context **res, GP_RetCode GP_LoadPNG(const char *src_path, GP_Context **res, GP_ProgressCallback *callback);
-#endif /* GP_PNG_H */ +/* + * Saves PNG to a file. + */ +GP_RetCode GP_SavePNG(const char *dst_path, const GP_Context *src, + GP_ProgressCallback *callback); + +#endif /* LOADERS_GP_PNG_H */ diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c index b013c42..d7da8ae 100644 --- a/libs/loaders/GP_PNG.c +++ b/libs/loaders/GP_PNG.c @@ -70,13 +70,25 @@ err: return GP_EBADFILE; }
+static const char *interlace_type_name(int interlace) +{ + switch (interlace) { + case PNG_INTERLACE_NONE: + return "none"; + case PNG_INTERLACE_ADAM7: + return "adam7"; + default: + return "unknown"; + } +} + GP_RetCode GP_ReadPNG(FILE *f, GP_Context **res, GP_ProgressCallback *callback) { png_structp png; png_infop png_info = NULL; png_uint_32 w, h; - int depth, color_type; + int depth, color_type, interlace_type; GP_PixelType pixel_type = GP_PIXEL_UNKNOWN; GP_RetCode ret;
@@ -107,9 +119,10 @@ GP_RetCode GP_ReadPNG(FILE *f, GP_Context **res, png_read_info(png, png_info);
png_get_IHDR(png, png_info, &w, &h, &depth, - &color_type, NULL, NULL, NULL); + &color_type, &interlace_type, NULL, NULL);
- GP_DEBUG(2, "Have %s%s PNG%s size %ux%u depth %i", + GP_DEBUG(2, "Have %s%s interlace %s PNG%s size %ux%u depth %i", + interlace_type_name(interlace_type), color_type & PNG_COLOR_MASK_PALETTE ? "pallete " : "", color_type & PNG_COLOR_MASK_COLOR ? "color" : "gray", color_type & PNG_COLOR_MASK_ALPHA ? " with alpha channel" : "", @@ -156,6 +169,7 @@ GP_RetCode GP_ReadPNG(FILE *f, GP_Context **res, }
if (pixel_type == GP_PIXEL_UNKNOWN) { + GP_DEBUG(1, "Unimplemented png format"); ret = GP_ENOIMPL; goto err2; } @@ -168,10 +182,11 @@ GP_RetCode GP_ReadPNG(FILE *f, GP_Context **res, }
uint32_t y; - + + /* start the actuall reading */ for (y = 0; y < h; y++) { - png_bytep addr = GP_PIXEL_ADDR(*res, 0, y); - png_read_rows(png, &addr, NULL, 1); + png_bytep row = GP_PIXEL_ADDR(*res, 0, y); + png_read_rows(png, &row, NULL, 1);
if (GP_ProgressCallbackReport(callback, y, h, w)) { GP_DEBUG(1, "Operation aborted"); @@ -204,3 +219,88 @@ GP_RetCode GP_LoadPNG(const char *src_path, GP_Context **res,
return GP_ReadPNG(f, res, callback); } + +GP_RetCode GP_SavePNG(const char *dst_path, const GP_Context *src, + GP_ProgressCallback *callback) +{ + FILE *f; + GP_RetCode ret; + png_structp png; + png_infop png_info = NULL; + + if (src->pixel_type != GP_PIXEL_RGB888) { + GP_DEBUG(1, "Can't save png with pixel type %s", + GP_PixelTypeName(src->pixel_type)); + return GP_ENOIMPL; + } + + f = fopen(dst_path, "wb"); + + if (f == NULL) { + GP_DEBUG(1, "Failed to open '%s' for writing: %s", + dst_path, strerror(errno)); + return GP_EBADFILE; + } + + png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (png == NULL) { + GP_DEBUG(1, "Failed to allocate PNG write buffer"); + ret = GP_ENOMEM; + goto err1; + } + + png_info = png_create_info_struct(png); + + if (png_info == NULL) { + GP_DEBUG(1, "Failed to allocate PNG info buffer"); + ret = GP_ENOMEM; + goto err2; + } + + if (setjmp(png_jmpbuf(png))) { + GP_DEBUG(1, "Failed to write PNG file :("); + ret = GP_EBADFILE; + goto err2; + } + + png_init_io(png, f); + png_set_IHDR(png, png_info, src->w, src->h, 8, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + /* start the actuall writing */ + png_write_info(png, png_info); + png_set_bgr(png); + + uint32_t y; + + for (y = 0; y < src->h; y++) { + png_bytep row = GP_PIXEL_ADDR(src, 0, y); + png_write_row(png, row); + + if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) { + GP_DEBUG(1, "Operation aborted"); + ret = GP_EINTR; + goto err2; + } + + } + + png_write_end(png, png_info); + png_destroy_write_struct(&png, &png_info); + + if (fclose(f)) { + GP_DEBUG(1, "Failed to close file '%s': %s", + dst_path, strerror(errno)); + return GP_EBADFILE; + } + + return GP_ESUCCESS; +err2: + png_destroy_write_struct(&png, png_info == NULL ? NULL : &png_info); +err1: + fclose(f); + unlink(dst_path); + return ret; +}
-----------------------------------------------------------------------
Summary of changes: include/loaders/GP_JPG.h | 16 +++++-- include/loaders/GP_PNG.h | 8 +++- libs/loaders/GP_JPG.c | 92 +++++++++++++++++++++++++++++++++++++- libs/loaders/GP_PNG.c | 112 +++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 215 insertions(+), 13 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.