-1

I have the source code for a video decoder application written in C, which I'm now porting on iphone.

My problem is as follows:

I have RGBA pixel data for a frame in a buffer that I need to display on the screen. My buffer is of type unsigned char. (I cannot change it to any other data type as the source code is too huge and not written by me.)

Most of the links I found on the net say about how to "draw and display pixels" on the screen or how to "display pixels present in an array", but none of then say how to "display pixel data present in a buffer".

I'm planning to use quartz 2D. All I need to do is just display the buffer contents on the screen. No modifications! Although my problem sounds very simple, there isn't any API that I could find to do the same. I couldn't find any appropriate link or document that was useful enough.

Kindly help! Thanks in advance.

Ereka
  • 103
  • 1
  • 10

1 Answers1

2

You can use the CGContext data structure to create a CGImage from raw pixel data. I've quickly written a basic example:

- (CGImageRef)drawBufferWidth:(size_t)width height:(size_t)height pixels:(void *)pixels
{
    unsigned char (*buf)[width][4] = pixels;


    static CGColorSpaceRef csp = NULL;
    if (!csp) {
        csp = CGColorSpaceCreateDeviceRGB();
    }

    CGContextRef ctx = CGBitmapContextCreate(
        buf,
        width,
        height,
        8, // 8 bits per pixel component
        width * 4, // 4 bytes per row
        csp,
        kCGImageAlphaPremultipliedLast
    );

    CGImageRef img = CGBitmapContextCreateImage(ctx);
    CGContextRelease(ctx);
    return img;
}

You can call this method like this (I've used a view controller):

- (void)viewDidLoad
{
    [super viewDidLoad];

    const size_t width = 320;
    const size_t height = 460;

    unsigned char (*buf)[width][4] = malloc(sizeof(*buf) * height);

    // fill up `buf` here
    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            buf[y][x][0] = x * 255 / width;
            buf[y][x][1] = y * 255 / height;
            buf[y][x][2] =   0;
            buf[y][x][3] = 255;
        }
    }

    CGImageRef img = [self drawBufferWidth:320 height:460 pixels:buf];
    self.imageView.image = [UIImage imageWithCGImage:img];
    CGImageRelease(img);
}
  • Thanks for the reply. I tried it out, but nothing is getting displayed on the screen. I'm supposed to create a property called imageView of type UIImageView in the view controller right? Is there anything else that I need to do? – Ereka Mar 18 '13 at 06:02
  • @Ereka That's not my fault. This is working code I've copy-pasted from the project I was working with. Double check everything you have, the error is **surely** not in this code. –  Mar 18 '13 at 06:03
  • I'm supposed to create a property called imageView of type UIImageView in the view controller right? – Ereka Mar 18 '13 at 06:16
  • @Ereka **And** either hook it up to an image view in Interface Builder, or alloc-init it and add it as a subview early in the initialization of the view controller. –  Mar 18 '13 at 06:17
  • Your part of the code is working fine now. I just need to modify my code a little to completely make it work. Thanks again! – Ereka Mar 18 '13 at 09:02
  • Hey, I just need to know one more thing. I'm calling drawBufferWIdth from my C file and passing buffer having the RGBA data as the parameter. I tried executing it, it is not displaying the image.. Do I need to modify anything after passing the buffer? Sorry to bother you again! – Ereka Mar 18 '13 at 10:04
  • Instead of UIImageView can I use CGContextDrawImage? – Ereka Mar 21 '13 at 11:31