Merge pull request #271 from gnustep/Endianess_BitmapRep

Improve Endianness support for BitmapRep
This commit is contained in:
Riccardo 2024-05-15 09:48:23 +02:00 committed by GitHub
commit 8913711a6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 123 additions and 43 deletions

View file

@ -2,7 +2,7 @@
<abstract>Bitmap image representation.</abstract>
Copyright (C) 1996-2017 Free Software Foundation, Inc.
Copyright (C) 1996-2024 Free Software Foundation, Inc.
Author: Adam Fedor <fedor@gnu.org>
Date: Feb 1996
@ -1552,6 +1552,7 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
[self _fillTIFFInfo: &info
usingCompression: compression
factor: factor];
if (NSTiffWrite(image, &info, [self bitmapData]) != 0)
{
[NSException raise: NSTIFFException format: @"Writing data"];
@ -2076,6 +2077,9 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
info->height = _pixelsHigh;
info->bitsPerSample = _bitsPerSample;
info->samplesPerPixel = _numColors;
info->isBigEndian = NO;
info->is16Bit = NO;
info->is32Bit = NO;
// resolution/density
info->xdpi = 0;
@ -2125,6 +2129,27 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
factor = 1;
info->quality = factor * 100;
info->error = 0;
if ((_format & NSBitmapFormatSixteenBitBigEndian) != 0)
{
info->isBigEndian = YES;
info->is16Bit = YES;
}
else if ((_format & NSBitmapFormatSixteenBitLittleEndian) != 0)
{
info->isBigEndian = NO;
info->is16Bit = YES;
}
else if ((_format & NSBitmapFormatThirtyTwoBitBigEndian) != 0)
{
info->isBigEndian = YES;
info->is32Bit = YES;
}
else if ((_format & NSBitmapFormatThirtyTwoBitLittleEndian) != 0)
{
info->isBigEndian = NO;
info->is32Bit = YES;
}
}
- (void) _premultiply

View file

@ -3,9 +3,9 @@
Functions for dealing with tiff images
Copyright (C) 1996 Free Software Foundation, Inc.
Copyright (C) 1996-2024 Free Software Foundation, Inc.
Written by: Adam Fedor <fedor@colorado.edu>
Written by: Adam Fedor <fedor@gnu.org>
Date: Feb 1996
This file is part of the GNUstep GUI Library.
@ -33,37 +33,42 @@
classes for general reading/writing of tiff files.
*/
#ifndef _GNUstep_H_tiff
#define _GNUstep_H_tiff
#ifndef _NSIMAGE_TIFF_H
#define _NSIMAGE_TIFF_H
#include <tiffio.h>
#include <inttypes.h>
/* Structure to store common information about a tiff. */
typedef struct {
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;
float xdpi;
float ydpi;
typedef struct
{
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;
float xdpi;
float ydpi;
char isBigEndian; /* meaningful only for 16 & 32 bit depths */
char is16Bit;
char is32Bit;
} NSTiffInfo;
typedef struct {
uint32_t size;
uint16_t *red;
uint16_t *green;
uint16_t *blue;
typedef struct
{
uint32_t size;
uint16_t *red;
uint16_t *green;
uint16_t *blue;
} NSTiffColormap;
typedef char* realloc_data_callback(char* data, long size);
@ -81,5 +86,5 @@ extern NSTiffColormap* NSTiffGetColormap(TIFF* image);
extern int NSTiffIsCodecConfigured(unsigned int codec);
#endif // _GNUstep_H_tiff
#endif // _NSIMAGE_TIFF_H

View file

@ -3,9 +3,9 @@
Functions for dealing with tiff images.
Copyright (C) 1996,1999-2010, 2017 Free Software Foundation, Inc.
Copyright (C) 1996-2024 Free Software Foundation, Inc.
Author: Adam Fedor <fedor@colorado.edu>
Author: Adam Fedor <fedor@gnu.org>
Date: Feb 1996
Support for writing tiffs: Richard Frith-Macdonald
@ -64,7 +64,9 @@
#import <Foundation/NSString.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSByteOrder.h>
#import "GSGuiPrivate.h"
#import <AppKit/NSBitmapImageRep.h>
#include <math.h>
#include <stdlib.h>
@ -78,13 +80,14 @@
typedef tsize_t tmsize_t;
#endif
typedef struct {
char* data;
typedef struct
{
char *data;
long size;
long position;
char mode;
char **outdata;
long *outposition;
char **outdata;
long *outposition;
} chandle_t;
static int tiff_error_handler_set = 0;
@ -464,21 +467,54 @@ NSTiffRead(TIFF *image, NSTiffInfo *info, unsigned char *data)
return error;
}
#define WRITE_SCANLINE(sample) \
if (TIFFWriteScanline(image, buf, row, sample) != 1) { \
error = 1; \
break; \
}
#define SWAP_LINE_ENDIANNESS \
if (info->is16Bit) \
{ \
uint16_t *inBuf = (uint16_t*)buf; \
uint16_t *outBuf = (uint16_t*)bufSwap; \
unsigned swapSample; \
for (swapSample = 0; swapSample < scan_line_size / 2; swapSample++) \
{ \
outBuf[swapSample] = GSSwapI16(inBuf[swapSample]); \
} \
} \
else if (info->is32Bit) \
{ \
uint32_t *inBuf = (uint32_t*)buf; \
uint32_t *outBuf = (uint32_t*)bufSwap; \
unsigned swapSample; \
for (swapSample = 0; swapSample < scan_line_size / 4; swapSample++) \
{ \
outBuf[swapSample] = GSSwapI32(inBuf[swapSample]); \
} \
}
#define WRITE_SCANLINE(sample) \
if (swapByteOrder) \
{ \
SWAP_LINE_ENDIANNESS; \
} \
else \
{ \
bufSwap = buf; \
} \
if (TIFFWriteScanline(image, bufSwap, row, sample) != 1) { \
error = 1; \
break; \
}
int
NSTiffWrite(TIFF *image, NSTiffInfo *info, unsigned char *data)
{
void* buf = (void*)data;
uint16_t sample_info[1];
void *buf = (void*)data;
void *bufSwap = nil;
uint16_t sample_info[1];
int i;
unsigned int row;
int error = 0;
tmsize_t scan_line_size;
BOOL swapByteOrder = NO;
if (info->numImages > 1)
{
@ -512,6 +548,18 @@ NSTiffWrite(TIFF *image, NSTiffInfo *info, unsigned char *data)
TIFFSetField(image, TIFFTAG_EXTRASAMPLES, info->extraSamples, sample_info);
scan_line_size = TIFFScanlineSize(image);
// check if image endianness is different from Host
if ((info->isBigEndian != 0) != (NSHostByteOrder() == NS_BigEndian) &&
(info->is16Bit || info->is32Bit))
{
swapByteOrder = YES;
}
if (swapByteOrder)
{
bufSwap = malloc(scan_line_size); // sizeof(unsigned char)
}
switch (info->photoInterp)
{
case PHOTOMETRIC_MINISBLACK:
@ -569,6 +617,10 @@ NSTiffWrite(TIFF *image, NSTiffInfo *info, unsigned char *data)
// Write out the directory as there may be more images comming
TIFFWriteDirectory(image);
TIFFFlush(image);
if (swapByteOrder)
{
free(bufSwap);
}
return error;
}
@ -684,5 +736,3 @@ int NSTiffIsCodecConfigured(unsigned int codec)
}
#endif
}