mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-25 08:10:59 +00:00
* Source/NSBitmapImageRep+JPEG.m: Try to handle images with alpha
or planar images correctly. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@40175 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
1a74105054
commit
89d8ad94be
2 changed files with 57 additions and 67 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2016-10-24 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
|
* Source/NSBitmapImageRep+JPEG.m: Try to handle images with alpha
|
||||||
|
or planar images correctly.
|
||||||
|
|
||||||
2016-10-24 04:03-EDT Gregory John Casamento <greg.casamento@gmail.com>
|
2016-10-24 04:03-EDT Gregory John Casamento <greg.casamento@gmail.com>
|
||||||
|
|
||||||
* Source/NSWorkspace.m: Change to GSLaunchd(...) function to
|
* Source/NSWorkspace.m: Change to GSLaunchd(...) function to
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
#import <Foundation/NSValue.h>
|
#import <Foundation/NSValue.h>
|
||||||
#import "AppKit/NSGraphics.h"
|
#import "AppKit/NSGraphics.h"
|
||||||
|
#import "NSBitmapImageRepPrivate.h"
|
||||||
#import "NSBitmapImageRep+JPEG.h"
|
#import "NSBitmapImageRep+JPEG.h"
|
||||||
#import "GSGuiPrivate.h"
|
#import "GSGuiPrivate.h"
|
||||||
|
|
||||||
|
@ -527,34 +528,31 @@ static void gs_jpeg_memory_dest_destroy (j_compress_ptr cinfo)
|
||||||
int height;
|
int height;
|
||||||
int row_stride;
|
int row_stride;
|
||||||
int quality = 90;
|
int quality = 90;
|
||||||
NSNumber *qualityNumber = nil;
|
NSNumber *qualityNumber;
|
||||||
NSNumber *progressiveNumber = nil;
|
NSNumber *progressiveNumber;
|
||||||
NSString *colorSpace = nil;
|
NSString *colorSpace;
|
||||||
BOOL isRGB;
|
|
||||||
struct jpeg_compress_struct cinfo;
|
struct jpeg_compress_struct cinfo;
|
||||||
struct gs_jpeg_error_mgr jerrMgr;
|
struct gs_jpeg_error_mgr jerrMgr;
|
||||||
JSAMPROW row_pointer[1]; // pointer to a single row
|
JSAMPROW row_pointer[1]; // pointer to a single row
|
||||||
|
|
||||||
// TODO: handles planar images
|
if ([self isPlanar] || [self hasAlpha])
|
||||||
|
|
||||||
if ([self isPlanar])
|
|
||||||
{
|
{
|
||||||
NSString * em = @"JPEG image rep: Planar Image, not handled yet !";
|
// note we will strip alpha from RGBA
|
||||||
if (errorMsg != NULL)
|
NSBitmapImageRep *converted = [self _convertToFormatBitsPerSample: _bitsPerSample
|
||||||
*errorMsg = em;
|
samplesPerPixel: [self hasAlpha] ? _numColors - 1 : _numColors
|
||||||
else
|
hasAlpha: NO
|
||||||
NSLog (@"JPEG image rep: Planar Image, not handled yet !");
|
isPlanar: NO
|
||||||
return nil;
|
colorSpaceName: _colorSpace
|
||||||
|
bitmapFormat: _format & ~NSAlphaNonpremultipliedBitmapFormat & ~NSAlphaFirstBitmapFormat
|
||||||
|
bytesPerRow: 0
|
||||||
|
bitsPerPixel: 0];
|
||||||
|
|
||||||
|
return [converted _JPEGRepresentationWithProperties: properties
|
||||||
|
errorMessage: errorMsg];
|
||||||
}
|
}
|
||||||
|
|
||||||
memset((void*)&cinfo, 0, sizeof(struct jpeg_compress_struct));
|
memset((void*)&cinfo, 0, sizeof(struct jpeg_compress_struct));
|
||||||
|
|
||||||
imageSource = [self bitmapData];
|
|
||||||
sPP = [self samplesPerPixel];
|
|
||||||
width = [self size].width;
|
|
||||||
height = [self size].height;
|
|
||||||
row_stride = width * sPP;
|
|
||||||
|
|
||||||
/* Establish the our custom error handler */
|
/* Establish the our custom error handler */
|
||||||
gs_jpeg_error_mgr_init(&jerrMgr);
|
gs_jpeg_error_mgr_init(&jerrMgr);
|
||||||
cinfo.err = jpeg_std_error(&jerrMgr.parent);
|
cinfo.err = jpeg_std_error(&jerrMgr.parent);
|
||||||
|
@ -580,33 +578,49 @@ static void gs_jpeg_memory_dest_destroy (j_compress_ptr cinfo)
|
||||||
|
|
||||||
gs_jpeg_memory_dest_create (&cinfo, &ret);
|
gs_jpeg_memory_dest_create (&cinfo, &ret);
|
||||||
|
|
||||||
// set parameters
|
|
||||||
|
|
||||||
colorSpace = [self colorSpaceName];
|
colorSpace = [self colorSpaceName];
|
||||||
isRGB = ([colorSpace isEqualToString: NSDeviceRGBColorSpace]
|
imageSource = [self bitmapData];
|
||||||
|| [colorSpace isEqualToString: NSCalibratedRGBColorSpace]);
|
sPP = [self samplesPerPixel];
|
||||||
|
width = [self size].width;
|
||||||
|
height = [self size].height;
|
||||||
|
row_stride = width * sPP;
|
||||||
|
|
||||||
|
// set parameters
|
||||||
cinfo.image_width = width;
|
cinfo.image_width = width;
|
||||||
cinfo.image_height = height;
|
cinfo.image_height = height;
|
||||||
// note we will strip alpha from RGBA
|
cinfo.input_components = sPP;
|
||||||
cinfo.input_components = (isRGB && [self hasAlpha])? 3 : sPP;
|
if (sPP == 1)
|
||||||
cinfo.in_color_space = JCS_UNKNOWN;
|
{
|
||||||
if (isRGB) cinfo.in_color_space = JCS_RGB;
|
cinfo.in_color_space = JCS_GRAYSCALE;
|
||||||
if (sPP == 1) cinfo.in_color_space = JCS_GRAYSCALE;
|
}
|
||||||
if ([colorSpace isEqualToString: NSDeviceCMYKColorSpace])
|
else if ([colorSpace isEqualToString: NSDeviceRGBColorSpace]
|
||||||
|
|| [colorSpace isEqualToString: NSCalibratedRGBColorSpace])
|
||||||
|
{
|
||||||
|
cinfo.in_color_space = JCS_RGB;
|
||||||
|
}
|
||||||
|
else if ([colorSpace isEqualToString: NSDeviceCMYKColorSpace])
|
||||||
|
{
|
||||||
cinfo.in_color_space = JCS_CMYK;
|
cinfo.in_color_space = JCS_CMYK;
|
||||||
if (cinfo.in_color_space == JCS_UNKNOWN)
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
NSLog(@"JPEG image rep: Using unknown color space with unpredictable results");
|
NSLog(@"JPEG image rep: Using unknown color space with unpredictable results");
|
||||||
|
|
||||||
|
gs_jpeg_memory_dest_destroy (&cinfo);
|
||||||
|
jpeg_destroy_compress(&cinfo);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
jpeg_set_defaults (&cinfo);
|
jpeg_set_defaults (&cinfo);
|
||||||
|
|
||||||
// set quality
|
// set quality
|
||||||
// we expect a value between 0..1, 0 being lowest, 1 highest quality
|
// we expect a value between 0..1, 0 being lowest, 1 highest quality
|
||||||
|
|
||||||
qualityNumber = [properties objectForKey: NSImageCompressionFactor];
|
qualityNumber = [properties objectForKey: NSImageCompressionFactor];
|
||||||
if (qualityNumber != nil)
|
if (qualityNumber != nil)
|
||||||
{
|
{
|
||||||
quality = (int) ([qualityNumber floatValue] * 100.0);
|
quality = (int) ([qualityNumber floatValue] * 100.0);
|
||||||
}
|
}
|
||||||
|
jpeg_set_quality (&cinfo, quality, TRUE);
|
||||||
|
|
||||||
// set progressive mode
|
// set progressive mode
|
||||||
progressiveNumber = [properties objectForKey: NSImageProgressive];
|
progressiveNumber = [properties objectForKey: NSImageProgressive];
|
||||||
|
@ -620,35 +634,9 @@ static void gs_jpeg_memory_dest_destroy (j_compress_ptr cinfo)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// compress the image
|
// compress the image
|
||||||
|
|
||||||
jpeg_set_quality (&cinfo, quality, TRUE);
|
|
||||||
jpeg_start_compress (&cinfo, TRUE);
|
jpeg_start_compress (&cinfo, TRUE);
|
||||||
|
|
||||||
if (isRGB && [self hasAlpha]) // strip alpha channel before encoding
|
|
||||||
{
|
|
||||||
unsigned char * RGB, * pRGB, * pRGBA;
|
|
||||||
unsigned int iRGB, iRGBA;
|
|
||||||
RGB = malloc(sizeof(unsigned char)*3*width);
|
|
||||||
while (cinfo.next_scanline < cinfo.image_height)
|
|
||||||
{
|
|
||||||
iRGBA = cinfo.next_scanline * row_stride;
|
|
||||||
pRGBA = &imageSource[iRGBA];
|
|
||||||
pRGB = RGB;
|
|
||||||
for (iRGB = 0; iRGB < 3*width; iRGB += 3)
|
|
||||||
{
|
|
||||||
memcpy(pRGB, pRGBA, 3);
|
|
||||||
pRGB +=3;
|
|
||||||
pRGBA +=4;
|
|
||||||
}
|
|
||||||
row_pointer[0] = RGB;
|
|
||||||
jpeg_write_scanlines (&cinfo, row_pointer, 1);
|
|
||||||
}
|
|
||||||
free(RGB);
|
|
||||||
}
|
|
||||||
else // no alpha channel
|
|
||||||
{
|
|
||||||
while (cinfo.next_scanline < cinfo.image_height)
|
while (cinfo.next_scanline < cinfo.image_height)
|
||||||
{
|
{
|
||||||
int index = cinfo.next_scanline * row_stride;
|
int index = cinfo.next_scanline * row_stride;
|
||||||
|
@ -656,12 +644,9 @@ static void gs_jpeg_memory_dest_destroy (j_compress_ptr cinfo)
|
||||||
row_pointer[0] = &imageSource[index];
|
row_pointer[0] = &imageSource[index];
|
||||||
jpeg_write_scanlines (&cinfo, row_pointer, 1);
|
jpeg_write_scanlines (&cinfo, row_pointer, 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
jpeg_finish_compress(&cinfo);
|
jpeg_finish_compress(&cinfo);
|
||||||
|
|
||||||
gs_jpeg_memory_dest_destroy (&cinfo);
|
gs_jpeg_memory_dest_destroy (&cinfo);
|
||||||
|
|
||||||
jpeg_destroy_compress(&cinfo);
|
jpeg_destroy_compress(&cinfo);
|
||||||
|
|
||||||
return AUTORELEASE(ret);
|
return AUTORELEASE(ret);
|
||||||
|
|
Loading…
Reference in a new issue