Created
October 6, 2014 11:49
-
-
Save uobikiemukot/85cb7a01f7dd161432ff to your computer and use it in GitHub Desktop.
support image 1/2 byte pel pixel image(grayscale (+ alpha)) and 4 bytes per pixel image (rgb + alpha)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/dither.c b/src/dither.c | |
index 4f777e2..5ac4eeb 100644 | |
--- a/src/dither.c | |
+++ b/src/dither.c | |
@@ -218,24 +218,64 @@ sixel_dither_get(int builtin_dither) | |
} | |
+void | |
+sixel_normalize_depth(unsigned char *dst, unsigned char *src, int width, int height, int depth) | |
+{ | |
+ int x, y, dst_offset, src_offset; | |
+ | |
+ for (y = 0; y < height; y++) { | |
+ for (x = 0; x < width; x++) { | |
+ src_offset = depth * (y * width + x); | |
+ dst_offset = 3 * (y * width + x); | |
+ if (depth <= 2) { /* grayscale (+ alpha) */ | |
+ *(dst + dst_offset + 0) = *(src + src_offset); | |
+ *(dst + dst_offset + 1) = *(src + src_offset); | |
+ *(dst + dst_offset + 2) = *(src + src_offset); | |
+ } else if (depth <= 4) { /* rgb (+ alpha) */ | |
+ *(dst + dst_offset + 0) = *(src + src_offset + 0); | |
+ *(dst + dst_offset + 1) = *(src + src_offset + 1); | |
+ *(dst + dst_offset + 2) = *(src + src_offset + 2); | |
+ } | |
+ } | |
+ } | |
+} | |
+ | |
+ | |
int | |
sixel_dither_initialize(sixel_dither_t *dither, unsigned char *data, | |
int width, int height, int depth, | |
int method_for_largest, int method_for_rep, | |
int quality_mode) | |
{ | |
- unsigned char *buf; | |
+ unsigned char *buf, *normalized_pixels; | |
+ | |
+ /* normalize depth */ | |
+ normalized_pixels = malloc(width * height * 3); | |
+ if (normalized_pixels == NULL) { | |
+ return (-1); | |
+ } | |
+ | |
+ if (depth != 3) { | |
+ sixel_normalize_depth(normalized_pixels, data, width, height, depth); | |
+ } else { | |
+ memcpy(normalized_pixels, data, width * height * 3); | |
+ } | |
+ if (normalized_pixels == NULL) { | |
+ return (-1); | |
+ } | |
- buf = LSQ_MakePalette(data, width, height, depth, | |
+ buf = LSQ_MakePalette(normalized_pixels, width, height, 3, | |
dither->reqcolors, &dither->ncolors, | |
&dither->origcolors, | |
dither->method_for_largest, | |
dither->method_for_rep, | |
dither->quality_mode); | |
if (buf == NULL) { | |
+ free(normalized_pixels); | |
return (-1); | |
} | |
- memcpy(dither->palette, buf, dither->ncolors * depth); | |
+ memcpy(dither->palette, buf, dither->ncolors * 3); | |
+ free(normalized_pixels); | |
free(buf); | |
dither->optimized = 1; | |
diff --git a/src/dither.h b/src/dither.h | |
index 8d7a16e..3fe39b9 100644 | |
--- a/src/dither.h | |
+++ b/src/dither.h | |
@@ -46,6 +46,8 @@ extern "C" { | |
/* apply palette */ | |
unsigned char * sixel_apply_palette(unsigned char *pixels, int width, int height, | |
sixel_dither_t *dither); | |
+void sixel_normalize_depth(unsigned char *dst, unsigned char *src, | |
+ int width, int height, int depth); | |
#ifdef __cplusplus | |
} | |
diff --git a/src/tosixel.c b/src/tosixel.c | |
index 8d841b2..5d06701 100644 | |
--- a/src/tosixel.c | |
+++ b/src/tosixel.c | |
@@ -368,14 +368,30 @@ int sixel_encode(unsigned char /* in */ *pixels, /* pixel bytes */ | |
sixel_output_t /* in */ *context) /* output context */ | |
{ | |
int ret; | |
- unsigned char *paletted_pixels; | |
+ unsigned char *paletted_pixels, *normalized_pixels; | |
sixel_dither_ref(dither); | |
+ /* normalize depth */ | |
+ normalized_pixels = malloc(width * height * 3); | |
+ if (normalized_pixels == NULL) | |
+ return (-1); | |
+ | |
+ if (depth != 3) { | |
+ sixel_normalize_depth(normalized_pixels, pixels, width, height, depth); | |
+ } else { | |
+ memcpy(normalized_pixels, pixels, width * height * 3); | |
+ } | |
+ if (normalized_pixels == NULL) { | |
+ sixel_dither_unref(dither); | |
+ return (-1); | |
+ } | |
+ | |
/* apply palette */ | |
- paletted_pixels = sixel_apply_palette(pixels, width, height, dither); | |
+ paletted_pixels = sixel_apply_palette(normalized_pixels, width, height, dither); | |
if (paletted_pixels == NULL) { | |
sixel_dither_unref(dither); | |
+ free(normalized_pixels); | |
return (-1); | |
} | |
@@ -384,6 +400,7 @@ int sixel_encode(unsigned char /* in */ *pixels, /* pixel bytes */ | |
dither->keycolor, context); | |
sixel_dither_unref(dither); | |
+ free(normalized_pixels); | |
free(paletted_pixels); | |
return 0; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment