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 f278f7d7683d97876757877353550e431700d180 (commit) via fae0a3810bc628f5e72e5e3147ccbb5b24f010e6 (commit) via 0fca9291826bed0f81d3583c7785260ef051eb25 (commit) from c404e7e68b3d6567519cb2fcb45ea5fc652add35 (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/f278f7d7683d97876757877353550e431700d...
commit f278f7d7683d97876757877353550e431700d180 Author: Cyril Hrubis metan@ucw.cz Date: Sun May 27 14:32:55 2012 +0200
examples: Add simple python dithering example
diff --git a/demos/py_simple/dither.py b/demos/py_simple/dither.py new file mode 100755 index 0000000..dae8838 --- /dev/null +++ b/demos/py_simple/dither.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +import sys + +import gfxprim.core as core +import gfxprim.loaders as loaders +import gfxprim.filters as filters + +def main(): + if len(sys.argv) != 2: + print("usage: dither.py image") + sys.exit(1) + + # Load Image + img = loaders.LoadImage(sys.argv[1], None) + # Use Floyd-Steinberg dithering + res = filters.FilterFloydSteinberg_RGB888_Alloc(img, core.C.PIXEL_G1, None) + # Save result into grayscale png + loaders.SavePNG(res, "out.png", None) + +if __name__ == '__main__': + main()
http://repo.or.cz/w/gfxprim.git/commit/fae0a3810bc628f5e72e5e3147ccbb5b24f01...
commit fae0a3810bc628f5e72e5e3147ccbb5b24f010e6 Author: Cyril Hrubis metan@ucw.cz Date: Sun May 27 14:31:25 2012 +0200
loaders: Add support for sawing Grayscale PNGs.
diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c index 381039c..3e8d6de 100644 --- a/libs/loaders/GP_PNG.c +++ b/libs/loaders/GP_PNG.c @@ -41,6 +41,8 @@
#include <png.h>
+#include "core/GP_BitSwap.h" + int GP_OpenPNG(const char *src_path, FILE **f) { uint8_t sig[8]; @@ -235,6 +237,128 @@ GP_Context *GP_LoadPNG(const char *src_path, GP_ProgressCallback *callback) return GP_ReadPNG(f, callback); }
+/* + * Maps gfxprim Pixel Type to the PNG format + */ +static int prepare_png_header(const GP_Context *src, png_structp png, + png_infop png_info, int *bit_endian_flag) +{ + int bit_depth, color_type; + + switch (src->pixel_type) { + case GP_PIXEL_BGR888: + case GP_PIXEL_RGB888: + bit_depth = 8; + color_type = PNG_COLOR_TYPE_RGB; + break; + case GP_PIXEL_G1: + bit_depth = 1; + color_type = PNG_COLOR_TYPE_GRAY; + break; + case GP_PIXEL_G2: + bit_depth = 2; + color_type = PNG_COLOR_TYPE_GRAY; + break; + case GP_PIXEL_G4: + bit_depth = 4; + color_type = PNG_COLOR_TYPE_GRAY; + break; + case GP_PIXEL_G8: + bit_depth = 8; + color_type = PNG_COLOR_TYPE_GRAY; + break; + default: + return 1; + break; + } + + /* If pointers weren't passed, just return it is okay */ + if (png == NULL || png_info == NULL) + return 0; + + png_set_IHDR(png, png_info, src->w, src->h, bit_depth, color_type, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + /* start the actuall writing */ + png_write_info(png, png_info); + + //png_set_packing(png); + + /* prepare for format conversion */ + switch (src->pixel_type) { + case GP_PIXEL_RGB888: + png_set_bgr(png); + break; + case GP_PIXEL_G1: + case GP_PIXEL_G2: + case GP_PIXEL_G4: + *bit_endian_flag = !src->bit_endian; + break; + default: + break; + } + + return 0; +} + +static int write_png_data_g_swap(const GP_Context *src, png_structp png, + GP_ProgressCallback *callback) +{ + unsigned int y; + uint8_t row[src->bytes_per_row]; + + for (y = 0; y < src->h; y++) { + memcpy(row, GP_PIXEL_ADDR(src, 0, y), src->bytes_per_row); + + switch (src->pixel_type) { + case GP_PIXEL_G1: + GP_BitSwapRow_B1(row, src->bytes_per_row); + break; + case GP_PIXEL_G2: + GP_BitSwapRow_B4(row, src->bytes_per_row); + break; + case GP_PIXEL_G4: + GP_BitSwapRow_B4(row, src->bytes_per_row); + break; + default: + return ENOSYS; + break; + } + + png_write_row(png, row); + + if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) { + GP_DEBUG(1, "Operation aborted"); + return ECANCELED; + } + } + + return 0; +} + +static int write_png_data(const GP_Context *src, png_structp png, + GP_ProgressCallback *callback, int bit_endian_flag) +{ + /* Look if we need to swap data when writing */ + if (bit_endian_flag) + return write_png_data_g_swap(src, png, callback); + + unsigned int 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"); + return ECANCELED; + } + } + + return 0; +} + int GP_SavePNG(const GP_Context *src, const char *dst_path, GP_ProgressCallback *callback) { @@ -245,8 +369,8 @@ int GP_SavePNG(const GP_Context *src, const char *dst_path,
GP_DEBUG(1, "Saving PNG Image '%s'", dst_path);
- if (src->pixel_type != GP_PIXEL_RGB888) { - GP_DEBUG(1, "Can't save png with pixel type %s", + if (prepare_png_header(src, NULL, NULL, NULL)) { + GP_DEBUG(1, "Can't save png with %s pixel type", GP_PixelTypeName(src->pixel_type)); return ENOSYS; } @@ -284,27 +408,14 @@ int GP_SavePNG(const GP_Context *src, const char *dst_path, }
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); + + int bit_endian_flag = 0; + /* Fill png header and prepare for data */ + prepare_png_header(src, png, png_info, &bit_endian_flag);
- if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) { - GP_DEBUG(1, "Operation aborted"); - err = ECANCELED; - goto err3; - } - - } + /* Write bitmap buffer */ + if ((err = write_png_data(src, png, callback, bit_endian_flag))) + goto err3;
png_write_end(png, png_info); png_destroy_write_struct(&png, &png_info);
http://repo.or.cz/w/gfxprim.git/commit/0fca9291826bed0f81d3583c7785260ef051e...
commit 0fca9291826bed0f81d3583c7785260ef051eb25 Author: Cyril Hrubis metan@ucw.cz Date: Sun May 27 14:29:35 2012 +0200
core: Add bit swap helpers.
diff --git a/include/core/GP_BitSwap.h b/include/core/GP_BitSwap.h new file mode 100644 index 0000000..5ad76ad --- /dev/null +++ b/include/core/GP_BitSwap.h @@ -0,0 +1,97 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2012 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + + /* + + Inline functions for swapping bits inside of the byte + + */ + +#ifndef CORE_GP_BIT_SWAP_H +#define CORE_GP_BIT_SWAP_H + +/* + * Reverse 1 bit blocks in the byte. + * + * Example: + * + * IN 10101110 + * OUT 01110101 + */ +static inline uint8_t GP_BIT_SWAP_B1(uint8_t byte) +{ + return ((byte * 0x0802LU & 0x22110LU) | + (byte * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; +} + +static inline void GP_BitSwapRow_B1(uint8_t *row, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) + row[i] = GP_BIT_SWAP_B1(row[i]); +} + +/* + * Reverse 2 bit blocks in the byte. + * + * Example: + * + * IN 10 11 01 00 + * OUT 00 01 11 10 + */ +static inline uint8_t GP_BIT_SWAP_B2(uint8_t byte) +{ + return ((byte & 0xC0) >> 6) | ((byte & 0x30) >> 2) | + ((byte & 0x0C) << 2) | ((byte & 0x03) << 6); +} + +static inline void GP_BitSwapRow_B2(uint8_t *row, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) + row[i] = GP_BIT_SWAP_B2(row[i]); +} + +/* + * Reverse 4 bit blocks in the byte. + * + * Example: + * + * IN 1011 0100 + * OUT 0100 1011 + */ +static inline uint8_t GP_BIT_SWAP_B4(uint8_t byte) +{ + return ((byte & 0xf0) >> 4) | ((byte & 0x0f) << 4); +} + +static inline void GP_BitSwapRow_B4(uint8_t *row, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) + row[i] = GP_BIT_SWAP_B4(row[i]); +} + +#endif /* CORE_GP_BIT_SWAP_H */
-----------------------------------------------------------------------
Summary of changes: demos/py_simple/dither.py | 21 +++ .../GP_GetPutPixel.c => include/core/GP_BitSwap.h | 80 ++++++++-- libs/loaders/GP_PNG.c | 155 +++++++++++++++++--- 3 files changed, 219 insertions(+), 37 deletions(-) create mode 100755 demos/py_simple/dither.py copy libs/core/GP_GetPutPixel.c => include/core/GP_BitSwap.h (55%)
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.