1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-12 17:37:33 +01:00
Telegram/thirdparty/PGPhotoEditor/PGPhotoEditorRawDataInput.m
2015-10-01 19:19:52 +03:00

156 lines
4.3 KiB
Objective-C

#import "PGPhotoEditorRawDataInput.h"
@interface PGPhotoEditorRawDataInput ()
{
CGSize _imageSize;
bool _processed;
dispatch_semaphore_t _updateSemaphore;
}
@end
@implementation PGPhotoEditorRawDataInput
- (instancetype)init
{
self = [super init];
if (self != nil)
{
_updateSemaphore = dispatch_semaphore_create(1);
_processed = false;
}
return self;
}
- (void)invalidate
{
}
- (instancetype)initWithBytes:(GLubyte *)bytes size:(CGSize)size
{
return [self initWithBytes:bytes size:size pixelFormat:GPUPixelFormatBGRA type:GPUPixelTypeUByte];
}
- (instancetype)initWithBytes:(GLubyte *)bytes size:(CGSize)size pixelFormat:(GPUPixelFormat)pixelFormat
{
return [self initWithBytes:bytes size:size pixelFormat:pixelFormat type:GPUPixelTypeUByte];
}
- (instancetype)initWithBytes:(GLubyte *)bytes size:(CGSize)size pixelFormat:(GPUPixelFormat)pixelFormat type:(GPUPixelType)pixelType
{
self = [self init];
if (self != nil)
{
_imageSize = size;
self.pixelFormat = pixelFormat;
self.pixelType = pixelType;
if (bytes != NULL)
[self uploadBytes:bytes];
}
return self;
}
- (void)dealloc
{
[outputFramebuffer enableReferenceCounting];
[outputFramebuffer unlock];
}
- (void)addTarget:(id<GPUImageInput>)newTarget atTextureLocation:(NSInteger)textureLocation
{
[super addTarget:newTarget atTextureLocation:textureLocation];
if (_processed)
{
[newTarget setInputSize:_imageSize atIndex:textureLocation];
[newTarget setInputFramebuffer:outputFramebuffer atIndex:textureLocation];
[newTarget newFrameReadyAtTime:kCMTimeIndefinite atIndex:textureLocation];
}
}
- (void)removeAllTargets
{
[super removeAllTargets];
_processed = false;
}
- (void)uploadBytes:(GLubyte *)bytes
{
[GPUImageContext useImageProcessingContext];
if (outputFramebuffer != nil)
{
[outputFramebuffer enableReferenceCounting];
[outputFramebuffer unlock];
}
outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:_imageSize textureOptions:self.outputTextureOptions onlyTexture:true];
[outputFramebuffer disableReferenceCounting];
glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]);
glTexImage2D(GL_TEXTURE_2D, 0, _pixelFormat==GPUPixelFormatRGB ? GL_RGB : GL_RGBA, (int)_imageSize.width, (int)_imageSize.height, 0, (GLint)_pixelFormat, (GLenum)_pixelType, bytes);
}
- (void)updateDataWithBytes:(GLubyte *)bytes size:(CGSize)size
{
_imageSize = size;
[self uploadBytes:bytes];
}
- (void)processData
{
_processed = true;
if (dispatch_semaphore_wait(_updateSemaphore, DISPATCH_TIME_NOW) != 0)
return;
runAsynchronouslyOnVideoProcessingQueue(^
{
CGSize pixelSizeOfImage = [self outputImageSize];
for (id<GPUImageInput> currentTarget in targets)
{
NSInteger indexOfObject = [targets indexOfObject:currentTarget];
NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue];
[currentTarget setInputSize:pixelSizeOfImage atIndex:textureIndexOfTarget];
[currentTarget setInputFramebuffer:outputFramebuffer atIndex:textureIndexOfTarget];
[currentTarget newFrameReadyAtTime:kCMTimeInvalid atIndex:textureIndexOfTarget];
}
dispatch_semaphore_signal(_updateSemaphore);
});
}
- (void)processDataForTimestamp:(CMTime)frameTime
{
_processed = true;
if (dispatch_semaphore_wait(_updateSemaphore, DISPATCH_TIME_NOW) != 0)
return;
runAsynchronouslyOnVideoProcessingQueue(^
{
CGSize pixelSizeOfImage = [self outputImageSize];
for (id<GPUImageInput> currentTarget in targets)
{
NSInteger indexOfObject = [targets indexOfObject:currentTarget];
NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue];
[currentTarget setInputSize:pixelSizeOfImage atIndex:textureIndexOfTarget];
[currentTarget newFrameReadyAtTime:frameTime atIndex:textureIndexOfTarget];
}
dispatch_semaphore_signal(_updateSemaphore);
});
}
- (CGSize)outputImageSize
{
return _imageSize;
}
@end