From ac7b0a280678493394580c3f1a6f85a4daffcd39 Mon Sep 17 00:00:00 2001 From: Ishotihadus Date: Sun, 27 May 2018 04:31:10 +0900 Subject: [PATCH] refactor rgb565 --- ext/decoders/native/main.c | 4 ++-- ext/decoders/native/rgb.c | 22 +++++++++------------- lib/mikunyan/decoders/image_decoder.rb | 2 +- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/ext/decoders/native/main.c b/ext/decoders/native/main.c index 4d16710..f507e82 100644 --- a/ext/decoders/native/main.c +++ b/ext/decoders/native/main.c @@ -8,9 +8,9 @@ static VALUE rb_decode_rgb565(VALUE self, VALUE rb_data, VALUE size, VALUE big) { if (RSTRING_LEN(rb_data) < FIX2LONG(size) * 2) rb_raise(rb_eStandardError, "Data size is not enough."); - uint8_t *image = (uint8_t*)malloc(FIX2LONG(size) * 3); + uint8_t *image = (uint8_t*)malloc(FIX2LONG(size) * 4); decode_rgb565((uint16_t*)RSTRING_PTR(rb_data), FIX2INT(size), RTEST(big), image); - VALUE ret = rb_str_new((char*)image, FIX2LONG(size) * 3); + VALUE ret = rb_str_new((char*)image, FIX2LONG(size) * 4); free(image); return ret; } diff --git a/ext/decoders/native/rgb.c b/ext/decoders/native/rgb.c index 6d4f7e6..d1ddd24 100644 --- a/ext/decoders/native/rgb.c +++ b/ext/decoders/native/rgb.c @@ -7,24 +7,20 @@ static inline int is_system_little() { void decode_rgb565(const uint16_t* data, const int size, const int is_big_endian, uint8_t* image) { const uint16_t *d = data; - uint8_t *p = image; if (is_big_endian == is_system_little()) { - for (int i = 0; i < size; i++, d++, p += 3) { - uint8_t r = *d & 0x00f8; - uint8_t g = (*d & 0x0007) << 5 | (*d & 0xe000) >> 11; - uint8_t b = (*d & 0x1f00) >> 5; + uint8_t *p = image; + for (int i = 0; i < size; i++, d++, p += 4) { + uint_fast8_t r = *d & 0x00f8; + uint_fast8_t g = (*d & 0x0007) << 5 | (*d & 0xe000) >> 11; + uint_fast8_t b = (*d & 0x1f00) >> 5; p[0] = r | r >> 5; p[1] = g | g >> 6; p[2] = b | b >> 5; + p[3] = 255; } } else { - for (int i = 0; i < size; i++, d++, p += 3) { - uint8_t r = (*d & 0xf800) >> 8; - uint8_t g = (*d & 0x07e0) >> 3; - uint8_t b = (*d & 0x001f) << 3; - p[0] = r | r >> 5; - p[1] = g | g >> 6; - p[2] = b | b >> 5; - } + uint32_t *p = (uint32_t*)image; + for (int i = 0; i < size; i++, d++, p++) + *p = (*d & 0xf800) >> 8 | *d >> 13 | (*d & 0x7e0) << 5 | (*d & 0x60) << 3 | *d << 19 | (*d & 0x1c) << 14 | 0xff000000; } } diff --git a/lib/mikunyan/decoders/image_decoder.rb b/lib/mikunyan/decoders/image_decoder.rb index fd6e858..edf7cd9 100644 --- a/lib/mikunyan/decoders/image_decoder.rb +++ b/lib/mikunyan/decoders/image_decoder.rb @@ -126,7 +126,7 @@ module Mikunyan # @param [Symbol] endian endianness of binary # @return [ChunkyPNG::Image] decoded image def self.decode_rgb565(width, height, bin, endian = :big) - ChunkyPNG::Image.from_rgb_stream(width, height, DecodeHelper.decode_rgb565(bin, width * height, endian == :big)).flip + ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_rgb565(bin, width * height, endian == :big)).flip end # Decode image from A8 binary