mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-06-02 07:10:59 +00:00
In _premultiply and _unpremultiply flag the format as changed.
Add fast path for 8 bit images. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@26131 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
f580b967f4
commit
1a100f8b80
2 changed files with 200 additions and 25 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2008-02-25 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
|
* Source/NSBitmapImageRep.m (-_premultiply, _unpremultiply): Flag
|
||||||
|
the format as changed. Add fast path for 8 bit images.
|
||||||
|
* Source/NSBitmapImageRep.m
|
||||||
|
(-_convertToFormatBitsPerSample:...bitsPerPixel:) New helper
|
||||||
|
method for image conversion. Not fully working.
|
||||||
|
|
||||||
2008-02-18 Fred Kiefer <FredKiefer@gmx.de>
|
2008-02-18 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
* Source/NSMenuView.m: Change to better respect the size of the
|
* Source/NSMenuView.m: Change to better respect the size of the
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "NSBitmapImageRep+PNM.h"
|
#include "NSBitmapImageRep+PNM.h"
|
||||||
|
|
||||||
#include <Foundation/NSArray.h>
|
#include <Foundation/NSArray.h>
|
||||||
|
#include <Foundation/NSAutoreleasePool.h>
|
||||||
#include <Foundation/NSData.h>
|
#include <Foundation/NSData.h>
|
||||||
#include <Foundation/NSDebug.h>
|
#include <Foundation/NSDebug.h>
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
|
@ -464,7 +465,7 @@
|
||||||
colorSpaceName: (NSString*)colorSpaceName
|
colorSpaceName: (NSString*)colorSpaceName
|
||||||
bitmapFormat: (NSBitmapFormat)bitmapFormat
|
bitmapFormat: (NSBitmapFormat)bitmapFormat
|
||||||
bytesPerRow: (int)rowBytes
|
bytesPerRow: (int)rowBytes
|
||||||
bitsPerPixel: (int)pixelBits;
|
bitsPerPixel: (int)pixelBits
|
||||||
{
|
{
|
||||||
if (!bps || !spp || !width || !height)
|
if (!bps || !spp || !width || !height)
|
||||||
{
|
{
|
||||||
|
@ -1901,8 +1902,6 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned int pixelData[5];
|
unsigned int pixelData[5];
|
||||||
int start, end, i, ai;
|
int start, end, i, ai;
|
||||||
float scale;
|
|
||||||
float alpha;
|
|
||||||
SEL getPSel = @selector(getPixel:atX:y:);
|
SEL getPSel = @selector(getPixel:atX:y:);
|
||||||
SEL setPSel = @selector(setPixel:atX:y:);
|
SEL setPSel = @selector(setPixel:atX:y:);
|
||||||
IMP getP = [self methodForSelector: getPSel];
|
IMP getP = [self methodForSelector: getPSel];
|
||||||
|
@ -1911,7 +1910,6 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
||||||
if (!_hasAlpha || !(_format & NSAlphaNonpremultipliedBitmapFormat))
|
if (!_hasAlpha || !(_format & NSAlphaNonpremultipliedBitmapFormat))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scale = (float)((1 << _bitsPerSample) - 1);
|
|
||||||
if (_format & NSAlphaFirstBitmapFormat)
|
if (_format & NSAlphaFirstBitmapFormat)
|
||||||
{
|
{
|
||||||
ai = 0;
|
ai = 0;
|
||||||
|
@ -1925,6 +1923,34 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
||||||
end = _numColors - 1;
|
end = _numColors - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_bitsPerSample == 8)
|
||||||
|
{
|
||||||
|
unsigned int a;
|
||||||
|
|
||||||
|
for (y = 0; y < _pixelsHigh; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < _pixelsWide; x++)
|
||||||
|
{
|
||||||
|
//[self getPixel: pixelData atX: x y: y];
|
||||||
|
getP(self, getPSel, pixelData, x, y);
|
||||||
|
a = pixelData[ai];
|
||||||
|
for (i = start; i < end; i++)
|
||||||
|
{
|
||||||
|
unsigned int t = a * pixelData[i] + 0x80;
|
||||||
|
|
||||||
|
pixelData[i] = ((t >> 8) + t) >> 8;
|
||||||
|
}
|
||||||
|
//[self setPixel: pixelData atX: x y: y];
|
||||||
|
setP(self, setPSel, pixelData, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float scale;
|
||||||
|
float alpha;
|
||||||
|
|
||||||
|
scale = (float)((1 << _bitsPerSample) - 1);
|
||||||
for (y = 0; y < _pixelsHigh; y++)
|
for (y = 0; y < _pixelsHigh; y++)
|
||||||
{
|
{
|
||||||
for (x = 0; x < _pixelsWide; x++)
|
for (x = 0; x < _pixelsWide; x++)
|
||||||
|
@ -1940,6 +1966,9 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
||||||
setP(self, setPSel, pixelData, x, y);
|
setP(self, setPSel, pixelData, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_format &= ~NSAlphaNonpremultipliedBitmapFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) _unpremultiply
|
- (void) _unpremultiply
|
||||||
|
@ -1947,8 +1976,6 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned int pixelData[5];
|
unsigned int pixelData[5];
|
||||||
int start, end, i, ai;
|
int start, end, i, ai;
|
||||||
float scale;
|
|
||||||
float alpha;
|
|
||||||
SEL getPSel = @selector(getPixel:atX:y:);
|
SEL getPSel = @selector(getPixel:atX:y:);
|
||||||
SEL setPSel = @selector(setPixel:atX:y:);
|
SEL setPSel = @selector(setPixel:atX:y:);
|
||||||
IMP getP = [self methodForSelector: getPSel];
|
IMP getP = [self methodForSelector: getPSel];
|
||||||
|
@ -1957,7 +1984,6 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
||||||
if (!_hasAlpha || (_format & NSAlphaNonpremultipliedBitmapFormat))
|
if (!_hasAlpha || (_format & NSAlphaNonpremultipliedBitmapFormat))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scale = (float)((1 << _bitsPerSample) - 1);
|
|
||||||
if (_format & NSAlphaFirstBitmapFormat)
|
if (_format & NSAlphaFirstBitmapFormat)
|
||||||
{
|
{
|
||||||
ai = 0;
|
ai = 0;
|
||||||
|
@ -1971,21 +1997,162 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
||||||
end = _numColors - 1;
|
end = _numColors - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_bitsPerSample == 8)
|
||||||
|
{
|
||||||
|
unsigned int a;
|
||||||
|
|
||||||
for (y = 0; y < _pixelsHigh; y++)
|
for (y = 0; y < _pixelsHigh; y++)
|
||||||
{
|
{
|
||||||
for (x = 0; x < _pixelsWide; x++)
|
for (x = 0; x < _pixelsWide; x++)
|
||||||
{
|
{
|
||||||
//[self getPixel: pixelData atX: x y: y];
|
//[self getPixel: pixelData atX: x y: y];
|
||||||
getP(self, getPSel, pixelData, x, y);
|
getP(self, getPSel, pixelData, x, y);
|
||||||
alpha = pixelData[ai] / scale;
|
a = pixelData[ai];
|
||||||
|
if (a != 0)
|
||||||
|
{
|
||||||
for (i = start; i < end; i++)
|
for (i = start; i < end; i++)
|
||||||
{
|
{
|
||||||
pixelData[i] /= alpha;
|
pixelData[i] = (pixelData[i] * 255) / a;
|
||||||
}
|
}
|
||||||
//[self setPixel: pixelData atX: x y: y];
|
//[self setPixel: pixelData atX: x y: y];
|
||||||
setP(self, setPSel, pixelData, x, y);
|
setP(self, setPSel, pixelData, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float scale;
|
||||||
|
float alpha;
|
||||||
|
|
||||||
|
scale = (float)((1 << _bitsPerSample) - 1);
|
||||||
|
for (y = 0; y < _pixelsHigh; y++)
|
||||||
|
{
|
||||||
|
unsigned int a;
|
||||||
|
|
||||||
|
for (x = 0; x < _pixelsWide; x++)
|
||||||
|
{
|
||||||
|
//[self getPixel: pixelData atX: x y: y];
|
||||||
|
getP(self, getPSel, pixelData, x, y);
|
||||||
|
a = pixelData[ai];
|
||||||
|
if (a != 0)
|
||||||
|
{
|
||||||
|
alpha = scale / a;
|
||||||
|
for (i = start; i < end; i++)
|
||||||
|
{
|
||||||
|
float new = pixelData[i] * alpha;
|
||||||
|
|
||||||
|
if (new > scale)
|
||||||
|
{
|
||||||
|
pixelData[i] = scale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pixelData[i] = new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//[self setPixel: pixelData atX: x y: y];
|
||||||
|
setP(self, setPSel, pixelData, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_format |= NSAlphaNonpremultipliedBitmapFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSBitmapImageRep *) _convertToFormatBitsPerSample: (int)bps
|
||||||
|
samplesPerPixel: (int)spp
|
||||||
|
hasAlpha: (BOOL)alpha
|
||||||
|
isPlanar: (BOOL)isPlanar
|
||||||
|
colorSpaceName: (NSString*)colorSpaceName
|
||||||
|
bitmapFormat: (NSBitmapFormat)bitmapFormat
|
||||||
|
bytesPerRow: (int)rowBytes
|
||||||
|
bitsPerPixel: (int)pixelBits
|
||||||
|
{
|
||||||
|
if (!pixelBits)
|
||||||
|
pixelBits = bps * ((isPlanar) ? 1 : spp);
|
||||||
|
if (!rowBytes)
|
||||||
|
rowBytes = ceil((float)_pixelsWide * pixelBits / 8);
|
||||||
|
|
||||||
|
// Do we already have the correct format?
|
||||||
|
if ((bps == _bitsPerSample) && (spp == _numColors)
|
||||||
|
&& (alpha == _hasAlpha) && (isPlanar == _isPlanar)
|
||||||
|
&& (bitmapFormat == _format) && (rowBytes == _bytesPerRow)
|
||||||
|
&& (pixelBits == _bitsPerPixel)
|
||||||
|
&& [_colorSpace isEqualToString: colorSpaceName])
|
||||||
|
{
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSBitmapImageRep* new;
|
||||||
|
|
||||||
|
new = [[NSBitmapImageRep alloc]
|
||||||
|
initWithBitmapDataPlanes: NULL
|
||||||
|
pixelsWide: _pixelsWide
|
||||||
|
pixelsHigh: _pixelsHigh
|
||||||
|
bitsPerSample: bps
|
||||||
|
samplesPerPixel: spp
|
||||||
|
hasAlpha: alpha
|
||||||
|
isPlanar: isPlanar
|
||||||
|
colorSpaceName: colorSpaceName
|
||||||
|
bitmapFormat: bitmapFormat
|
||||||
|
bytesPerRow: rowBytes
|
||||||
|
bitsPerPixel: pixelBits];
|
||||||
|
|
||||||
|
if ([_colorSpace isEqualToString: colorSpaceName])
|
||||||
|
{
|
||||||
|
SEL getPSel = @selector(getPixel:atX:y:);
|
||||||
|
SEL setPSel = @selector(setPixel:atX:y:);
|
||||||
|
IMP getP = [self methodForSelector: getPSel];
|
||||||
|
IMP setP = [new methodForSelector: setPSel];
|
||||||
|
unsigned int pixelData[5];
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
for (y = 0; y < _pixelsHigh; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < _pixelsWide; x++)
|
||||||
|
{
|
||||||
|
//[self getPixel: pixelData atX: x y: y];
|
||||||
|
getP(self, getPSel, pixelData, x, y);
|
||||||
|
// FIXME: Here we may need to resort, scale, pre-multiply
|
||||||
|
// the pixel data and add alpha. Or do the opposite :-)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//[new setPixel: pixelData atX: x y: y];
|
||||||
|
setP(new, setPSel, pixelData, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SEL getCSel = @selector(colorAtX:y:);
|
||||||
|
SEL setCSel = @selector(setColor:atX:y:);
|
||||||
|
IMP getC = [self methodForSelector: getCSel];
|
||||||
|
IMP setC = [new methodForSelector: setCSel];
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (j = 0; j < _pixelsHigh; j++)
|
||||||
|
{
|
||||||
|
CREATE_AUTORELEASE_POOL(pool);
|
||||||
|
|
||||||
|
for (i = 0; i < _pixelsWide; i++)
|
||||||
|
{
|
||||||
|
NSColor *c;
|
||||||
|
|
||||||
|
//c = [self colorAtX: i y: j];
|
||||||
|
c = getC(self, getCSel, i, j);
|
||||||
|
//[new setColor: c atX: i y: j];
|
||||||
|
setC(new, setCSel, c, i, j);
|
||||||
|
}
|
||||||
|
RELEASE(pool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AUTORELEASE(new);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue