diff options
author | dcommander <dcommander@632fc199-4ca6-4c93-a231-07263d6284db> | 2014-08-30 20:33:49 +0000 |
---|---|---|
committer | dcommander <dcommander@632fc199-4ca6-4c93-a231-07263d6284db> | 2014-08-30 20:33:49 +0000 |
commit | ab7c6aa3e127153d7b8f493c7416c658e6925345 (patch) | |
tree | 4228f28ecd7f76cf82afa7d431cd8ea98180b158 /wrbmp.c | |
parent | 3ce37ce93d5c712b6d6c9c857ed0409c7c084d53 (diff) |
Fix issues with RGB565 color conversion on big endian machines. The RGB565 routines are now abstracted in a separate file, with separate little-endian and big-endian versions defined at compile time through the use of macros (this is similar to how the colorspace extension routines work.) This allows big-endian machines to take advantage of the same performance optimizations as little-endian machines, and it retains the performance on little-endian machines, since the conditional branch for endianness is at a very coarse-grained level.
git-svn-id: svn://svn.code.sf.net/p/libjpeg-turbo/code/trunk@1398 632fc199-4ca6-4c93-a231-07263d6284db
Diffstat (limited to 'wrbmp.c')
-rw-r--r-- | wrbmp.c | 30 |
1 files changed, 20 insertions, 10 deletions
@@ -5,6 +5,7 @@ * Copyright (C) 1994-1996, Thomas G. Lane. * libjpeg-turbo Modifications: * Copyright (C) 2013, Linaro Limited. + * Copyright (C) 2014, D. R. Commander. * For conditions of distribution and use, see the accompanying README file. * * This file contains routines to write output images in Microsoft "BMP" @@ -64,6 +65,15 @@ LOCAL(void) write_colormap int map_entry_size); +static inline boolean is_big_endian(void) +{ + int test_value = 1; + if(*(char *)&test_value != 1) + return TRUE; + return FALSE; +} + + /* * Write some pixel data. * In this module rows_supplied will always be 1. @@ -93,18 +103,18 @@ put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, outptr = image_ptr[0]; if(cinfo->out_color_space == JCS_RGB565) { - #define red_mask 0xF800 - #define green_mask 0x7E0 - #define blue_mask 0x1F - unsigned char r, g, b; + boolean big_endian = is_big_endian(); unsigned short *inptr2 = (unsigned short *)inptr; for (col = cinfo->output_width; col > 0; col--) { - r = (*inptr2 & red_mask) >> 11; - g = (*inptr2 & green_mask) >> 5; - b = (*inptr2 & blue_mask); - outptr[0] = b << 3; - outptr[1] = g << 2; - outptr[2] = r << 3; + if (big_endian) { + outptr[0] = (*inptr2 >> 5) & 0xF8; + outptr[1] = ((*inptr2 << 5) & 0xE0) | ((*inptr2 >> 11) & 0x1C); + outptr[2] = *inptr2 & 0xF8; + } else { + outptr[0] = (*inptr2 << 3) & 0xF8; + outptr[1] = (*inptr2 >> 3) & 0xFC; + outptr[2] = (*inptr2 >> 8) & 0xF8; + } outptr += 3; inptr2++; } |