* Fix compiler warnings

* Attempt to sort out byte order for 15 bit images.

* Try to get integer types from standard location

* Remove extra swap code by using more complex condition.
Thanks to Riccardo Mottola.
This commit is contained in:
Fred Kiefer 2021-11-08 22:46:25 +01:00 committed by GitHub
parent 6ecfa261f6
commit a047b10a51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 163 additions and 79 deletions

View file

@ -27,7 +27,8 @@
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
@interface GSNamedColorPicker: NSColorPicker <NSColorPickingCustom, NSTextFieldDelegate>
@interface GSNamedColorPicker: NSColorPicker <NSColorPickingCustom, NSTextFieldDelegate,
NSComboBoxDataSource>
{
NSView *baseView;
NSComboBox *cb;

View file

@ -90,7 +90,24 @@ typedef enum _NSBitmapFormat
{
NSAlphaFirstBitmapFormat = 1,
NSAlphaNonpremultipliedBitmapFormat = 2,
NSFloatingPointSamplesBitmapFormat = 4
NSFloatingPointSamplesBitmapFormat = 4,
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, MAC_OS_X_VERSION_10_14)
NS16BitLittleEndianBitmapFormat = (1 << 8),
NS32BitLittleEndianBitmapFormat = (1 << 9),
NS16BitBigEndianBitmapFormat = (1 << 10),
NS32BitBigEndianBitmapFormat = (1 << 11),
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_12, GS_API_LATEST)
NSBitmapFormatAlphaFirst = 1,
NSBitmapFormatAlphaNonpremultiplied = (1 << 1),
NSBitmapFormatFloatingPointSamples = (1 << 2),
NSBitmapFormatSixteenBitLittleEndian = (1 << 8),
NSBitmapFormatThirtyTwoBitLittleEndian = (1 << 9),
NSBitmapFormatSixteenBitBigEndian = (1 << 10),
NSBitmapFormatThirtyTwoBitBigEndian = (1 << 11)
#endif
} NSBitmapFormat;
typedef enum _NSImageRepLoadStatus

View file

@ -106,6 +106,7 @@ static void reader_func(png_structp png_struct, png_bytep data,
BOOL alpha;
int bpp;
NSString *colorspace;
NSBitmapFormat bitmapFormat = NSAlphaNonpremultipliedBitmapFormat;
reader_struct_t reader;
@ -228,6 +229,15 @@ static void reader_func(png_structp png_struct, png_bytep data,
png_read_image(png_struct, row_pointers);
}
if (depth == 16)
{
bitmapFormat |= NSBitmapFormatSixteenBitBigEndian;
}
else if (depth == 32)
{
bitmapFormat |= NSBitmapFormatThirtyTwoBitBigEndian;
}
self = [self initWithBitmapDataPlanes: &buf
pixelsWide: width
pixelsHigh: height
@ -236,7 +246,7 @@ static void reader_func(png_structp png_struct, png_bytep data,
hasAlpha: alpha
isPlanar: NO
colorSpaceName: colorspace
bitmapFormat: NSAlphaNonpremultipliedBitmapFormat
bitmapFormat: bitmapFormat
bytesPerRow: bytes_per_row
bitsPerPixel: bpp];

View file

@ -670,33 +670,62 @@
* this is strictly necessary for OpenStep tiffs.
*/
static unsigned int
_get_bit_value(unsigned char *base, long msb_off, int bit_width)
_get_bit_value(unsigned char *base, long msb_off, int bit_width,
NSBitmapFormat format)
{
long lsb_off, byte1, byte2;
int shift, value;
if (bit_width == 16)
{
long byte1 = msb_off / 8;
long byte2 = byte1 + 1;
uint16_t value;
/*
* Firstly we calculate the position of the msb and lsb in terms
* of bit offsets and thus byte offsets. The shift is the number of
* spare bits left in the byte containing the lsb
*/
lsb_off= msb_off+bit_width-1;
byte1= msb_off/8;
byte2= lsb_off/8;
shift= 7-(lsb_off%8);
if ((NSHostByteOrder() == NS_BigEndian && !(format & NSBitmapFormatSixteenBitLittleEndian)) ||
(NSHostByteOrder() == NS_LittleEndian && (format & NSBitmapFormatSixteenBitBigEndian)))
{
value = base[byte2] | base[byte1] << 8;
}
else
{
value = base[byte1] | base[byte2] << 8;
}
/*
* We now get the value from the byte array, possibly using two bytes if
* the required set of bits crosses the byte boundary. This is then shifted
* down to it's correct position and extraneous bits masked off before
* being returned.
*/
value=base[byte2];
if (byte1!=byte2)
value|= base[byte1]<<8;
value >>= shift;
return value;
}
else if (bit_width == 32)
{
// FIXME Currently not handled
return 0;
}
else
{
long lsb_off, byte1, byte2;
unsigned int shift, value;
return value & ((1<<bit_width)-1);
/*
* Firstly we calculate the position of the msb and lsb in terms
* of bit offsets and thus byte offsets. The shift is the number of
* spare bits left in the byte containing the lsb
*/
lsb_off = msb_off + bit_width - 1;
byte1 = msb_off / 8;
byte2 = lsb_off / 8;
shift = 7 - (lsb_off % 8);
/*
* We now get the value from the byte array, possibly using two bytes if
* the required set of bits crosses the byte boundary. This is then shifted
* down to it's correct position and extraneous bits masked off before
* being returned.
*/
value = base[byte2];
if (byte1 != byte2)
{
value |= base[byte1] << 8;
}
value >>= shift;
return value & ((1 << bit_width) - 1);
}
}
/**
@ -732,7 +761,7 @@ _get_bit_value(unsigned char *base, long msb_off, int bit_width)
for (i = 0; i < _numColors; i++)
{
pixelData[i] = _get_bit_value(_imagePlanes[i] + line_offset,
offset, _bitsPerSample);
offset, _bitsPerSample, _format);
}
}
}
@ -752,7 +781,7 @@ _get_bit_value(unsigned char *base, long msb_off, int bit_width)
for (i = 0; i < _numColors; i++)
{
pixelData[i] = _get_bit_value(_imagePlanes[0] + line_offset,
offset, _bitsPerSample);
offset, _bitsPerSample, _format);
offset += _bitsPerSample;
}
}
@ -761,35 +790,62 @@ _get_bit_value(unsigned char *base, long msb_off, int bit_width)
static void
_set_bit_value(unsigned char *base, long msb_off, int bit_width,
unsigned int value)
NSBitmapFormat format, unsigned int value)
{
long lsb_off, byte1, byte2;
int shift;
int all;
if (bit_width == 16)
{
long byte1 = msb_off / 8;
long byte2 = byte1 + 1;
uint16_t value16 = value;
/*
* Firstly we calculate the position of the msb and lsb in terms
* of bit offsets and thus byte offsets. The shift is the number of
* spare bits left in the byte containing the lsb
*/
lsb_off= msb_off+bit_width-1;
byte1= msb_off/8;
byte2= lsb_off/8;
shift= 7-(lsb_off%8);
if ((NSHostByteOrder() == NS_BigEndian && !(format & NSBitmapFormatSixteenBitLittleEndian)) ||
(NSHostByteOrder() == NS_LittleEndian && (format & NSBitmapFormatSixteenBitBigEndian)))
{
base[byte1] = (value16 >> 8);
base[byte2] = (value16 & 255);
}
else
{
base[byte2] = (value16 >> 8);
base[byte1] = (value16 & 255);
}
}
else if (bit_width == 32)
{
// FIXME Currently not handled
}
else
{
long lsb_off, byte1, byte2;
int shift;
int all;
/*
* We now set the value in the byte array, possibly using two bytes if
* the required set of bits crosses the byte boundary. This value is
* first shifted up to it's correct position and extraneous bits are
* masked off.
*/
value &= ((1<<bit_width)-1);
value <<= shift;
all = ((1<<bit_width)-1) << shift;
/*
* Firstly we calculate the position of the msb and lsb in terms
* of bit offsets and thus byte offsets. The shift is the number of
* spare bits left in the byte containing the lsb
*/
lsb_off = msb_off + bit_width - 1;
byte1 = msb_off / 8;
byte2 = lsb_off/ 8;
shift = 7 - (lsb_off % 8);
if (byte1 != byte2)
base[byte1] = (value >> 8) | (base[byte1] & ~(all >> 8));
base[byte2] = (value & 255) | (base[byte2] & ~(all & 255));
/*
* We now set the value in the byte array, possibly using two bytes if
* the required set of bits crosses the byte boundary. This value is
* first shifted up to it's correct position and extraneous bits are
* masked off.
*/
value &= ((1 << bit_width) - 1);
value <<= shift;
all = ((1 << bit_width) - 1) << shift;
if (byte1 != byte2)
{
base[byte1] = (value >> 8) | (base[byte1] & ~(all >> 8));
}
base[byte2] = (value & 255) | (base[byte2] & ~(all & 255));
}
}
/**
@ -831,7 +887,7 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
for (i = 0; i < _numColors; i++)
{
_set_bit_value(_imagePlanes[i] + line_offset,
offset, _bitsPerSample, pixelData[i]);
offset, _bitsPerSample, _format, pixelData[i]);
}
}
}
@ -851,7 +907,7 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
for (i = 0; i < _numColors; i++)
{
_set_bit_value(_imagePlanes[0] + line_offset,
offset, _bitsPerSample, pixelData[i]);
offset, _bitsPerSample, _format, pixelData[i]);
offset += _bitsPerSample;
}
}

View file

@ -37,21 +37,21 @@
#define _GNUstep_H_tiff
#include <tiffio.h>
#include <sys/types.h>
#include <inttypes.h>
/* Structure to store common information about a tiff. */
typedef struct {
uint16 numImages; /* number of images in tiff */
uint16 imageNumber; /* number of current image */
uint32 subfileType;
uint32 width;
uint32 height;
uint16 bitsPerSample; /* number of bits per data channel */
uint16 samplesPerPixel; /* number of channels per pixel */
uint16 planarConfig; /* meshed or separate */
uint16 photoInterp; /* photometric interpretation of bitmap data, */
uint16 compression;
uint16 extraSamples; /* Alpha */
uint16_t numImages; /* number of images in tiff */
uint16_t imageNumber; /* number of current image */
uint32_t subfileType;
uint32_t width;
uint32_t height;
uint16_t bitsPerSample; /* number of bits per data channel */
uint16_t samplesPerPixel; /* number of channels per pixel */
uint16_t planarConfig; /* meshed or separate */
uint16_t photoInterp; /* photometric interpretation of bitmap data, */
uint16_t compression;
uint16_t extraSamples; /* Alpha */
int assocAlpha;
int quality; /* compression quality (for jpeg) 1 to 255 */
int error;
@ -60,10 +60,10 @@ typedef struct {
} NSTiffInfo;
typedef struct {
uint32 size;
uint16 *red;
uint16 *green;
uint16 *blue;
uint32_t size;
uint16_t *red;
uint16_t *green;
uint16_t *blue;
} NSTiffColormap;
typedef char* realloc_data_callback(char* data, long size);

View file

@ -271,7 +271,7 @@ NSTiffInfo *
NSTiffGetInfo(int imageNumber, TIFF* image)
{
NSTiffInfo* info;
uint16 *sample_info = NULL;
uint16_t *sample_info = NULL;
if (image == NULL)
return NULL;
@ -328,7 +328,7 @@ NSTiffGetInfo(int imageNumber, TIFF* image)
}
{
uint16 resolution_unit;
uint16_t resolution_unit;
float xres, yres;
if (TIFFGetField(image, TIFFTAG_XRESOLUTION, &xres)
&& TIFFGetField(image, TIFFTAG_YRESOLUTION, &yres))
@ -369,9 +369,9 @@ NSTiffRead(TIFF *image, NSTiffInfo *info, unsigned char *data)
int i;
unsigned int row, col;
int error = 0;
uint8* outP;
uint8* buf;
uint8* raster;
uint8_t* outP;
uint8_t* buf;
uint8_t* raster;
NSTiffColormap* map;
tmsize_t scan_line_size;
@ -389,7 +389,7 @@ NSTiffRead(TIFF *image, NSTiffInfo *info, unsigned char *data)
scan_line_size = TIFFScanlineSize(image);
buf = _TIFFmalloc(scan_line_size);
raster = (uint8 *)data;
raster = (uint8_t *)data;
outP = raster;
switch (info->photoInterp)
{
@ -419,7 +419,7 @@ NSTiffRead(TIFF *image, NSTiffInfo *info, unsigned char *data)
{
for (row = 0; row < info->height; ++row)
{
uint8 *inP;
uint8_t *inP;
READ_SCANLINE(0);
inP = buf;
for (col = 0; col < info->width; col++)
@ -474,7 +474,7 @@ int
NSTiffWrite(TIFF *image, NSTiffInfo *info, unsigned char *data)
{
void* buf = (void*)data;
uint16 sample_info[1];
uint16_t sample_info[1];
int i;
unsigned int row;
int error = 0;