Beispiel #1
0
Picture *Picture::yuv8_to_uyvy8(void) {
    int i, j;
    uint16_t u, v;
    uint8_t y1, y2;

    Picture *out = Picture::alloc(this->w, this->h, 2*this->w, UYVY8);
    uint8_t *in_ptr, *out_ptr;

    for (i = 0; i < this->h; i++) {
        in_ptr = this->scanline(i);
        out_ptr = out->scanline(i);

        for (j = 0; j < this->w; j += 2) {
            y1 = *in_ptr++;
            u = *in_ptr++;
            v = *in_ptr++;
            y2 = *in_ptr++;
            u += *in_ptr++;
            v += *in_ptr++;

            u /= 2;
            v /= 2;
    
            *out_ptr++ = u;
            *out_ptr++ = y1;
            *out_ptr++ = v;
            *out_ptr++ = y2;
        }
    }

    return out;
}
Beispiel #2
0
Picture *Picture::from_png(const char *filename) {
    cairo_surface_t *pngs = cairo_image_surface_create_from_png(filename);

    if (cairo_surface_status(pngs) != CAIRO_STATUS_SUCCESS) {
        cairo_surface_destroy(pngs);
        throw std::runtime_error("Failed to load PNG to Cairo surface");
    }

    cairo_format_t nf = cairo_image_surface_get_format(pngs);

    if (nf != CAIRO_FORMAT_ARGB32 && nf != CAIRO_FORMAT_RGB24) {
        cairo_surface_destroy(pngs);
        throw std::runtime_error("PNG uses unsupported pixel format");
    } 

    Picture *ret = Picture::alloc(
        cairo_image_surface_get_width(pngs),
        cairo_image_surface_get_height(pngs),
        4*cairo_image_surface_get_width(pngs),
        BGRA8
    );
        
    int xcopy = 4*ret->w;
    int stride = cairo_image_surface_get_stride(pngs);
    uint8_t *data = (uint8_t *)cairo_image_surface_get_data(pngs);

    /* copy data */
    for (int ycopy = 0; ycopy < ret->h; ++ycopy) {
        memcpy(ret->scanline(ycopy), data + stride * ycopy, xcopy);
    }
    
    cairo_surface_destroy(pngs);
    return ret;
}
Beispiel #3
0
Picture *Picture::uyvy8_to_yuv8(void) {
    int i, j;
    uint8_t u, y1, v, y2;
    Picture *out = Picture::alloc(this->w, this->h, 3*this->w, YUV8);
    uint8_t *in_ptr, *out_ptr;

    for (i = 0; i < this->h; i++) {
        in_ptr = this->scanline(i);
        out_ptr = out->scanline(i);

        for (j = 0; j < this->w; j+=2) {
            u = *in_ptr++;
            y1 = *in_ptr++;
            v = *in_ptr++;
            y2 = *in_ptr++;

            *out_ptr++ = y1;
            *out_ptr++ = u;
            *out_ptr++ = v;

            *out_ptr++ = y2;
            *out_ptr++ = u;
            *out_ptr++ = v;
        }
    }

    return out;
}
Beispiel #4
0
Picture *Picture::bgra8_to_yuva8(void) {
    int i, j;
    uint8_t r, g, b, a;
    uint16_t y, u, v;

    Picture *out = Picture::alloc(this->w, this->h, 4*this->w, YUVA8);
    uint8_t *pix_ptr, *out_ptr;

    for (i = 0; i < this->h; i++) {
        pix_ptr = this->scanline(i);
        out_ptr = out->scanline(i);
        for (j = 0; j < this->w; j++) {            
            b = *pix_ptr++;
            g = *pix_ptr++;
            r = *pix_ptr++;
            a = *pix_ptr++;

            y = 16 + (r * 66 + g * 129 + b * 25) / 256;
            u = 128 + (b * 112 - g * 74 - r * 37) / 256;
            v = 128 + (r * 112 - g * 94 - b * 18) / 256;

            *out_ptr++ = y;
            *out_ptr++ = u;
            *out_ptr++ = v;
            *out_ptr++ = a;
        }
    }
    
    return out;
}
Beispiel #5
0
Picture *Picture::bgra8_to_rgb8(void) {
    int i, j;
    uint8_t r, g, b, a;

    Picture *out = Picture::alloc(this->w, this->h, 3*this->w, RGB8);
    uint8_t *pix_ptr, *out_ptr;

    for (i = 0; i < this->h; i++) {
        pix_ptr = this->scanline(i);
        out_ptr = out->scanline(i);
        for (j = 0; j < this->w; j++) {            
            b = *pix_ptr++;
            g = *pix_ptr++;
            r = *pix_ptr++;
            a = *pix_ptr++;

            *out_ptr++ = r;
            *out_ptr++ = g;
            *out_ptr++ = b;
        }
    }
    
    return out;

}
Beispiel #6
0
Picture *Picture::rgb8_to_uyvy8(void) {
    int i, j;
    uint8_t r, g, b;
    uint16_t y1, y2, u, v;

    /* UYVY8 = 4 bytes/2 pixels (w must be even) */
    assert(this->w % 2 == 0);
    Picture *out = Picture::alloc(this->w, this->h, 2*this->w, UYVY8);
    uint8_t *pix_ptr, *out_ptr;

    for (i = 0; i < this->h; i++) {
        pix_ptr = this->scanline(i);
        out_ptr = out->scanline(i);
        for (j = 0; j < this->w; j += 2) {            
            r = *pix_ptr++;
            g = *pix_ptr++;
            b = *pix_ptr++;

            y1 = 16 + (r * 66 + g * 129 + b * 25) / 256;
            u = 128 + (b * 112 - g * 74 - r * 37) / 256;
            v = 128 + (r * 112 - g * 94 - b * 18) / 256;

            r = *pix_ptr++;
            g = *pix_ptr++;
            b = *pix_ptr++;

            y2 = 16 + (r * 66 + g * 129 + b * 25) / 256;
            u += 128 + (b * 112 - g * 74 - r * 37) / 256;
            v += 128 + (r * 112 - g * 94 - b * 18) / 256;
            
            u >>= 1;
            v >>= 1;

            *out_ptr++ = u;
            *out_ptr++ = y1;
            *out_ptr++ = v;
            *out_ptr++ = y2;
        }
    }
    
    return out;
}
Beispiel #7
0
/* (maybe not anymore??) */
Picture *Picture::uyvy8_to_rgb8(void) {
    int i, j;
    int16_t r, g, b;
    uint8_t u, y1, v, y2;
    Picture *out = Picture::alloc(this->w, this->h, 3*this->w, RGB8);
    uint8_t *in_ptr, *out_ptr;

    for (i = 0; i < this->h; i++) {
        in_ptr = this->scanline(i);
        out_ptr = out->scanline(i);

        for (j = 0; j < this->w; j += 2) {
            u = *in_ptr++;
            y1 = *in_ptr++;
            v = *in_ptr++;
            y2 = *in_ptr++;

            r = (298 * y1 + 409 * v) / 256 - 223;
            g = (298 * y1 - 100 * u - 208 * v) / 256 + 135;
            b = (298 * y1 + 516 * u) / 256 - 277;

            *out_ptr++ = SCLAMP(r);
            *out_ptr++ = SCLAMP(g);
            *out_ptr++ = SCLAMP(b);

            r = (298 * y2 + 409 * v) / 256 - 223;
            g = (298 * y2 - 100 * u - 208 * v) / 256 + 135;
            b = (298 * y2 + 516 * u) / 256 - 277;

            *out_ptr++ = SCLAMP(r);
            *out_ptr++ = SCLAMP(g);
            *out_ptr++ = SCLAMP(b);
        }
    }

    return out;
}