darling-cocotron/CoreGraphics/O2Surface.h

274 lines
10 KiB
Objective-C

/*------------------------------------------------------------------------
*
* Derivative of the OpenVG 1.0.1 Reference Implementation
* -------------------------------------
*
* Copyright (c) 2007 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and /or associated documentation files
* (the "Materials "), to deal in the Materials without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Materials,
* and to permit persons to whom the Materials are furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
* THE USE OR OTHER DEALINGS IN THE MATERIALS.
*
*-------------------------------------------------------------------*/
#import <Foundation/NSObject.h>
#import "O2Image.h"
#import "VGmath.h"
typedef unsigned int RIuint32;
typedef short RIint16;
typedef unsigned int VGbitfield;
typedef enum {
VG_TILE_FILL,
VG_TILE_PAD,
VG_TILE_REPEAT,
} VGTilingMode;
typedef enum {
VG_DRAW_IMAGE_NORMAL,
VG_DRAW_IMAGE_MULTIPLY,
VG_DRAW_IMAGE_STENCIL,
} O2SurfaceMode;
typedef enum {
VG_RED = (1 << 3),
VG_GREEN = (1 << 2),
VG_BLUE = (1 << 1),
VG_ALPHA = (1 << 0)
} O2SurfaceChannel;
typedef enum {
VG_CLEAR_MASK = 0x1500,
VG_FILL_MASK = 0x1501,
VG_SET_MASK = 0x1502,
VG_UNION_MASK = 0x1503,
VG_INTERSECT_MASK = 0x1504,
VG_SUBTRACT_MASK = 0x1505
} VGMaskOperation;
typedef struct {
int x;
int y;
int width;
int height;
} O2IntRect;
static inline O2IntRect O2IntRectInit(int x,int y,int width,int height) {
O2IntRect result={x,y,width,height};
return result;
}
#define RI_INT32_MAX (0x7fffffff)
#define RI_INT32_MIN (-0x7fffffff-1)
static inline int RI_INT_ADDSATURATE(int a, int b) { RI_ASSERT(b >= 0); int r = a + b; return (r >= a) ? r : RI_INT32_MAX; }
static inline O2IntRect O2IntRectIntersect(O2IntRect self,O2IntRect other) {
if(self.width >= 0 && other.width >= 0 && self.height >= 0 && other.height >= 0)
{
int xmin = RI_INT_MIN(RI_INT_ADDSATURATE(self.x, self.width), RI_INT_ADDSATURATE(other.x, other.width));
self.x = RI_INT_MAX(self.x, other.x);
self.width = RI_INT_MAX(xmin - self.x, 0);
int ymin = RI_INT_MIN(RI_INT_ADDSATURATE(self.y, self.height), RI_INT_ADDSATURATE(other.y, other.height));
self.y = RI_INT_MAX(self.y, other.y);
self.height = RI_INT_MAX(ymin - self.y, 0);
}
else
{
self.x = 0;
self.y = 0;
self.width = 0;
self.height = 0;
}
return self;
}
/*-------------------------------------------------------------------*//*!
* \brief A class representing color for processing and converting it
* to and from various surface formats.
*//*-------------------------------------------------------------------*/
typedef struct VGColor {
O2Float r;
O2Float g;
O2Float b;
O2Float a;
VGColorInternalFormat m_format;
} VGColor;
static inline VGColor VGColorFromRGBAffff(O2argb32f rgba,VGColorInternalFormat format){
VGColor result;
result.r=rgba.r;
result.g=rgba.g;
result.b=rgba.b;
result.a=rgba.a;
result.m_format=format;
return result;
}
static inline O2argb32f O2argb32fFromColor(VGColor color){
O2argb32f result;
result.r=color.r;
result.g=color.g;
result.b=color.b;
result.a=color.a;
return result;
}
static inline VGColor VGColorZero(){
VGColor result;
result.r=0;
result.g=0;
result.b=0;
result.a=0;
result.m_format=VGColor_lRGBA;
return result;
}
static inline VGColor VGColorRGBA(O2Float cr, O2Float cg, O2Float cb, O2Float ca, VGColorInternalFormat cs){
VGColor result;
RI_ASSERT(cs == VGColor_lRGBA || cs == VGColor_sRGBA || cs == VGColor_lRGBA_PRE || cs == VGColor_sRGBA_PRE || cs == VGColor_lLA || cs == VGColor_sLA || cs == VGColor_lLA_PRE || cs == VGColor_sLA_PRE);
result.r=cr;
result.g=cg;
result.b=cb;
result.a=ca;
result.m_format=cs;
return result;
}
static inline VGColor VGColorMultiplyByFloat(VGColor c,O2Float f){
return VGColorRGBA(c.r*f, c.g*f, c.b*f, c.a*f, c.m_format);
}
static inline VGColor VGColorAdd(VGColor c0,VGColor c1){
RI_ASSERT(c0.m_format == c1.m_format);
return VGColorRGBA(c0.r+c1.r, c0.g+c1.g, c0.b+c1.b, c0.a+c1.a, c0.m_format);
}
static inline VGColor VGColorSubtract(VGColor result,VGColor c1){
RI_ASSERT(result.m_format == c1.m_format);
result.r -= c1.r;
result.g -= c1.g;
result.b -= c1.b;
result.a -= c1.a;
return result;
}
//clamps nonpremultiplied colors and alpha to [0,1] range, and premultiplied alpha to [0,1], colors to [0,a]
static inline VGColor VGColorClamp(VGColor result){
result.a = RI_CLAMP(result.a,0.0f,1.0f);
O2Float u = (result.m_format & VGColorPREMULTIPLIED) ? result.a : (O2Float)1.0f;
result.r = RI_CLAMP(result.r,0.0f,u);
result.g = RI_CLAMP(result.g,0.0f,u);
result.b = RI_CLAMP(result.b,0.0f,u);
return result;
}
static inline VGColor VGColorPremultiply(VGColor result){
if(!(result.m_format & VGColorPREMULTIPLIED)) {
result.r *= result.a; result.g *= result.a; result.b *= result.a; result.m_format = (VGColorInternalFormat)(result.m_format | VGColorPREMULTIPLIED);
}
return result;
}
static inline VGColor VGColorUnpremultiply(VGColor result){
if(result.m_format & VGColorPREMULTIPLIED) {
O2Float ooa = (result.a != 0.0f) ? 1.0f/result.a : (O2Float)0.0f;
result.r *= ooa; result.g *= ooa; result.b *= ooa;
result.m_format = (VGColorInternalFormat) (result.m_format & ~VGColorPREMULTIPLIED);
}
return result;
}
VGColor VGColorConvert(VGColor result,VGColorInternalFormat outputFormat);
static inline void O2argb32fConvertSpan(O2argb32f *span,int length,VGColorInternalFormat fromFormat,VGColorInternalFormat toFormat){
if(fromFormat!=toFormat){
int i;
for(i=0;i<length;i++)
span[i]=O2argb32fFromColor(VGColorConvert(VGColorFromRGBAffff(span[i],fromFormat),toFormat));
}
}
@class O2Surface;
typedef void (*O2SurfaceWriteSpan_RGBA8888)(O2Surface *self,int x,int y,O2argb8u *span,int length);
typedef void (*O2SurfaceWriteSpan_RGBAffff)(O2Surface *self,int x,int y,O2argb32f *span,int length);
@interface O2Surface : O2Image {
unsigned char *_pixelBytes;
O2SurfaceWriteSpan_RGBA8888 _writeRGBA8888;
O2SurfaceWriteSpan_RGBAffff _writeRGBAffff;
BOOL m_ownsData;
VGPixelDecode m_desc;
}
-initWithBytes:(void *)bytes width:(size_t)width height:(size_t)height bitsPerComponent:(size_t)bitsPerComponent bytesPerRow:(size_t)bytesPerRow colorSpace:(O2ColorSpaceRef)colorSpace bitmapInfo:(O2BitmapInfo)bitmapInfo;
-(void *)pixelBytes;
-(void)setWidth:(size_t)width height:(size_t)height reallocateOnlyIfRequired:(BOOL)roir;
BOOL O2SurfaceIsValidFormat(int format);
void O2SurfaceClear(O2Surface *self,VGColor clearColor, int x, int y, int w, int h);
void O2SurfaceBlit(O2Surface *self,O2Surface * src, int sx, int sy, int dx, int dy, int w, int h, BOOL dither);
void O2SurfaceMask(O2Surface *self,O2Surface* src, VGMaskOperation operation, int x, int y, int w, int h);
VGColor O2SurfaceReadPixel(O2Image *self,int x, int y);
void O2SurfaceWritePixel(O2Surface *self,int x, int y, VGColor c);
void O2SurfaceWriteSpan_lRGBA8888_PRE(O2Surface *self,int x,int y,O2argb8u *span,int length);
void O2SurfaceWriteSpan_lRGBAffff_PRE(O2Surface *self,int x,int y,O2argb32f *span,int length);
void O2SurfaceWriteFilteredPixel(O2Surface *self,int x, int y, VGColor c, VGbitfield channelMask);
void O2SurfaceWriteMaskPixel(O2Surface *self,int x, int y, O2Float m); //can write only to VG_A_8
typedef struct O2GaussianKernel *O2GaussianKernelRef;
O2GaussianKernelRef O2CreateGaussianKernelWithDeviation(O2Float stdDeviation);
O2GaussianKernelRef O2GaussianKernelRetain(O2GaussianKernelRef kernel);
void O2GaussianKernelRelease(O2GaussianKernelRef kernel);
void O2SurfaceColorMatrix(O2Surface *self,O2Surface * src, const O2Float* matrix, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);
void O2SurfaceConvolve(O2Surface *self,O2Surface * src, int kernelWidth, int kernelHeight, int shiftX, int shiftY, const RIint16* kernel, O2Float scale, O2Float bias, VGTilingMode tilingMode, VGColor edgeFillColor, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);
void O2SurfaceSeparableConvolve(O2Surface *self,O2Surface * src, int kernelWidth, int kernelHeight, int shiftX, int shiftY, const RIint16* kernelX, const RIint16* kernelY, O2Float scale, O2Float bias, VGTilingMode tilingMode, VGColor edgeFillColor, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);
void O2SurfaceGaussianBlur(O2Surface *self,O2Image * src, O2GaussianKernelRef kernel,O2ColorRef color);
void O2SurfaceLookup(O2Surface *self,O2Surface * src, const uint8_t * redLUT, const uint8_t * greenLUT, const uint8_t * blueLUT, const uint8_t * alphaLUT, BOOL outputLinear, BOOL outputPremultiplied, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);
void O2SurfaceLookupSingle(O2Surface *self,O2Surface * src, const RIuint32 * lookupTable, O2SurfaceChannel sourceChannel, BOOL outputLinear, BOOL outputPremultiplied, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);
@end