2023-04-05 16:07:16 +04:00

199 lines
6.2 KiB
Objective-C

#import "TGPaintUtils.h"
#import "TGPhotoEditorUtils.h"
#import "LegacyComponentsInternal.h"
#import <zlib.h>
void TGPaintHasGLError_(const char* file, int line) {
GLenum error = glGetError();
if (error != 0)
{
NSString *message;
switch (error)
{
case GL_INVALID_ENUM:
message = @"GL_INVALID_ENUM";
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
message = @"GL_INVALID_FRAMEBUFFER_OPERATION";
break;
case GL_INVALID_OPERATION:
message = @"GL_INVALID_OPERATION";
break;
case GL_INVALID_VALUE:
message = @"GL_INVALID_VALUE";
break;
case GL_OUT_OF_MEMORY:
message = @"GL_OUT_OF_MEMORY";
break;
default:
message = [NSString stringWithFormat:@"UNKNOWN: 0x%x", error];
break;
}
TGLegacyLog(@"PAINT ERROR: glGetError %@ at %s:%d", message, file, line);
}
}
void TGSetupColorUniform(GLint location, UIColor *color)
{
NSInteger componentsCount = CGColorGetNumberOfComponents(color.CGColor);
const CGFloat *components = CGColorGetComponents(color.CGColor);
CGFloat red = 0.0f;
CGFloat green = 0.0f;
CGFloat blue = 0.0f;
CGFloat alpha = 1.0f;
if (componentsCount == 4)
{
red = components[0];
green = components[1];
blue = components[2];
alpha = components[3];
}
else
{
red = green = blue = components[0];
}
glUniform4f(location, (GLfloat)red, (GLfloat)green, (GLfloat)blue, (GLfloat)alpha);
}
UIImage *TGPaintCombineImages(UIImage *background, UIImage *foreground, bool opaque)
{
return TGPaintCombineCroppedImages(background, foreground, opaque, CGSizeZero, CGRectNull, UIImageOrientationUp, 0, false);
}
UIImage *TGPaintCombineCroppedImages(UIImage *background, UIImage *foreground, bool opaque, CGSize originalSize, CGRect cropRect, UIImageOrientation cropOrientation, CGFloat cropRotation, bool mirrored)
{
if (foreground == nil)
return background;
CGFloat width = TGOrientationIsSideward(cropOrientation, NULL) ? background.size.height : background.size.width;
CGFloat scale = originalSize.width / foreground.size.width / cropRect.size.width * width;
CGFloat pRatio = foreground.size.width / originalSize.width;
CGSize rotatedContentSize = TGRotatedContentSize(foreground.size, cropRotation);
UIGraphicsBeginImageContextWithOptions(background.size, opaque, 1.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect backgroundRect = CGRectMake(0, 0, background.size.width, background.size.height);
[background drawInRect:backgroundRect blendMode:kCGBlendModeCopy alpha:1.0f];
if (!CGSizeEqualToSize(originalSize, CGSizeZero))
{
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, background.size.width / 2.0f, background.size.height / 2.0f);
transform = CGAffineTransformScale(transform, scale, scale);
transform = CGAffineTransformRotate(transform, TGRotationForOrientation(cropOrientation));
transform = CGAffineTransformTranslate(transform, (rotatedContentSize.width / 2 - CGRectGetMidX(cropRect) * pRatio), (rotatedContentSize.height / 2 - CGRectGetMidY(cropRect) * pRatio));
transform = CGAffineTransformRotate(transform, cropRotation);
CGContextConcatCTM(context, transform);
if (mirrored)
CGContextScaleCTM(context, -1.0f, 1.0f);
[foreground drawAtPoint:CGPointMake(-foreground.size.width / 2.0f, -foreground.size.height / 2.0f) blendMode:kCGBlendModeNormal alpha:1.0f];
}
else
{
[foreground drawInRect:backgroundRect];
}
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
NSData *TGPaintGZipInflate(NSData *data)
{
if (data.length == 0)
return data;
NSUInteger fullLength = data.length;
NSUInteger halfLength = data.length / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength:fullLength + halfLength];
bool done = false;
int status;
z_stream strm;
strm.next_in = (Bytef *)data.bytes;
strm.avail_in = (uint32_t)data.length;
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit2(&strm, (15+32)) != Z_OK)
return nil;
while (!done)
{
if (strm.total_out >= decompressed.length)
[decompressed increaseLengthBy:halfLength];
strm.next_out = decompressed.mutableBytes + strm.total_out;
strm.avail_out = (uint32_t)(decompressed.length - strm.total_out);
status = inflate (&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END)
done = true;
else if (status != Z_OK)
break;
}
if (inflateEnd (&strm) != Z_OK)
return nil;
if (done)
{
[decompressed setLength:strm.total_out];
return [NSData dataWithData:decompressed];
}
return nil;
}
NSData *TGPaintGZipDeflate(NSData *data)
{
if (data.length == 0)
return data;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in = (Bytef *)data.bytes;
strm.avail_in = (uint32_t)data.length;
if (deflateInit2(&strm, Z_BEST_SPEED, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK)
return nil;
NSMutableData *compressed = [NSMutableData dataWithLength:16384];
do
{
if (strm.total_out >= compressed.length)
[compressed increaseLengthBy:16384];
strm.next_out = compressed.mutableBytes + strm.total_out;
strm.avail_out = (uint32_t)(compressed.length - strm.total_out);
deflate(&strm, Z_FINISH);
} while (strm.avail_out == 0);
deflateEnd(&strm);
[compressed setLength:strm.total_out];
return [NSData dataWithData:compressed];
}