Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(570438)

Unified Diff: examples/analyzer.cc

Issue 815: Render analyzer frame using cairo
Patch Set: Render analyzer frame using cairo Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « configure.ac ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: examples/analyzer.cc
diff --git a/examples/analyzer.cc b/examples/analyzer.cc
index 95c96d650f465a21d7d267f573d8b9fae77fddac..764012338b0613b3ef98ce30fe87bef30af1ed11 100644
--- a/examples/analyzer.cc
+++ b/examples/analyzer.cc
@@ -30,6 +30,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
#include <string.h>
#include <wx/wx.h>
#include <wx/dcbuffer.h>
+#include <cairo.h>
#include <ogg/ogg.h>
@@ -54,6 +55,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
# define OD_BLOCK_SIZE4x4(bsize, bstride, bx, by) \
((bsize)[((by) >> 1)*(bstride) + ((bx) >> 1)])
+od_img* img_clone(od_img* input) {
+ od_img *img;
+ od_img_plane *iplane;
+ od_img_plane *inputplane;
+ int pli;
+ img = (od_img *)malloc(sizeof(*img));
+ img->nplanes = input->nplanes;
+ img->width = input->width;
+ img->height = input->height;
+ for (pli = 0; pli < img->nplanes; pli++) {
+ iplane = img->planes + pli;
+ inputplane = input->planes + pli;
+ iplane->data = (unsigned char *)malloc(inputplane->ystride*img->height);
+ iplane->xdec = inputplane->xdec;
+ iplane->ydec = inputplane->ydec;
+ iplane->xstride = inputplane->xstride;
+ iplane->ystride = inputplane->ystride;
+ memcpy(iplane->data, inputplane->data, inputplane->ystride*img->height);
+ }
+ return img;
+}
+
class DaalaDecoder {
private:
FILE *input;
@@ -574,8 +597,84 @@ ogg_int64_t block_edge_luma(ogg_int64_t yval) {
return yval > 50 ? yval >> 1 : yval + 15;
}
+cairo_surface_t* create_from_img(od_img *img) {
+ unsigned char *y_row;
+ unsigned char *u_row;
+ unsigned char *v_row;
+ unsigned char *xrgb;
+ unsigned char *rgb;
+ int w;
+ int h;
+ int x;
+ int y;
+ int i;
+ int u_hdec;
+ int u_vdec;
+ int v_hdec;
+ int v_vdec;
+ cairo_surface_t *cs;
+ unsigned char * pixels;
+
+ w=img->width;
+ h=img->height;
+ u_hdec=img->planes[1].xdec;
+ u_vdec=img->planes[1].ydec;
+ v_hdec=img->planes[2].xdec;
+ v_vdec=img->planes[2].ydec;
+ y_row=img->planes[0].data;
+ u_row=img->planes[1].data;
+ v_row=img->planes[2].data;
+
+ pixels = (unsigned char *)malloc(sizeof(*pixels)*4*w*h);
+
+ /* convert the YUV image into our xRGB pixels buffer (Cairo requires
+ unpacked 32 bit RGB with one unused byte). This code works for
+ 420, 422 and 444 */
+ xrgb = pixels;
+ for(y=0;y<h;y++){
+ for(x=0;x<w;x++){
+ unsigned int r;
+ unsigned int g;
+ unsigned int b;
+ int64_t yval;
+ int64_t cbval;
+ int64_t crval;
+ yval = y_row[x] - 16;
+ cbval = u_row[x>>u_hdec] - 128;
+ crval = v_row[x>>v_hdec] - 128;
+ r = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
+ 2916394880000LL*yval + 4490222169144LL*crval, 9745792000LL), 65535);
+ g = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
+ 2916394880000LL*yval - 534117096223LL*cbval - 1334761232047LL*crval,
+ 9745792000LL), 65535);
+ b = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
+ 2916394880000LL*yval + 5290866304968LL*cbval, 9745792000LL), 65535);
+ xrgb[4*x+0] = (unsigned char)(b >> 8);
+ xrgb[4*x+1] = (unsigned char)(g >> 8);
+ xrgb[4*x+2] = (unsigned char)(r >> 8);
+ xrgb[4*x+3] = 0;
+ }
+ y_row+=img->planes[0].ystride;
+ u_row+=img->planes[1].ystride&-((y&1)|!u_vdec);
+ v_row+=img->planes[2].ystride&-((y&1)|!v_vdec);
+ xrgb+=4*w;
+ }
+
+ /* hand pixels to Cairo */
+ cs=cairo_image_surface_create_for_data(pixels,CAIRO_FORMAT_ARGB32,w,h,w*4);
+ if(cairo_surface_status(cs)!=CAIRO_STATUS_SUCCESS){
+ cairo_surface_destroy(cs);
+ return NULL;
+ }
+ return cs;
+}
+
void TestPanel::render() {
- od_img *img = &dd.img;
+ od_img *img = img_clone(&dd.img);
+ cairo_surface_t *cs;
+ cairo_t *cr;
+ cairo_pattern_t *p;
+ cairo_surface_t *output_surface;
/* Assume both chroma planes are decimated the same */
int xdec = img->planes[1].xdec;
int ydec = img->planes[1].ydec;
@@ -704,44 +803,47 @@ void TestPanel::render() {
yval = 255 * ((i + j) & 1);
pmask = OD_ALL_MASK;
}
- if (pmask & OD_LUMA_MASK) {
- yval -= 16;
- } else {
- yval = 128;
- }
- cbval = ((pmask & OD_CB_MASK) >> 1) * (cbval - 128);
- crval = ((pmask & OD_CR_MASK) >> 2) * (crval - 128);
- /*This is intentionally slow and very accurate.*/
- rval = OD_CLAMPI(0, (ogg_int32_t)OD_DIV_ROUND(
- 2916394880000LL*yval + 4490222169144LL*crval, 9745792000LL), 65535);
- gval = OD_CLAMPI(0, (ogg_int32_t)OD_DIV_ROUND(
- 2916394880000LL*yval - 534117096223LL*cbval - 1334761232047LL*crval,
- 9745792000LL), 65535);
- bval = OD_CLAMPI(0, (ogg_int32_t)OD_DIV_ROUND(
- 2916394880000LL*yval + 5290866304968LL*cbval, 9745792000LL), 65535);
- unsigned char *px_row = p;
- for (int v = 0; v < zoom; v++) {
- unsigned char *px = px_row;
- for (int u = 0; u < zoom; u++) {
- *(px + 0) = (unsigned char)(rval >> 8);
- *(px + 1) = (unsigned char)(gval >> 8);
- *(px + 2) = (unsigned char)(bval >> 8);
- px += 3;
- }
- px_row += p_stride;
+ if (!(pmask & OD_LUMA_MASK)) {
+ yval = 144;
}
+ cbval = ((pmask & OD_CB_MASK) >> 1) * (cbval);
+ crval = ((pmask & OD_CR_MASK) >> 2) * (crval);
+ *y = OD_CLAMPI(16,yval,235);
+ *cb = OD_CLAMPI(16,cbval,235);
+ *cr = OD_CLAMPI(16,crval,235);
int dc = ((y - y_row) & 1) | (1 - xdec);
y++;
cb += dc;
cr += dc;
- p += zoom*3;
}
int dc = -((j & 1) | (1 - ydec));
y_row += y_stride;
cb_row += dc & cb_stride;
cr_row += dc & cr_stride;
- p_row += zoom*p_stride;
}
+ cs = create_from_img(img);
+ cairo_surface_flush(cs);
+ output_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
+ getDisplayWidth(), getDisplayHeight());
+ cr = cairo_create(output_surface);
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+ cairo_scale(cr, zoom, zoom);
+ cairo_set_source_surface (cr, cs, 0, 0);
+ p = cairo_get_source(cr);
+ cairo_pattern_set_filter(p, CAIRO_FILTER_NEAREST);
+ cairo_paint(cr);
+ cairo_surface_flush(output_surface);
+ unsigned char *cairo_pixels = cairo_image_surface_get_data(output_surface);
+ unsigned char *wx_pixels = pixels;
+ for(int i = 0; i < getDisplayWidth()*getDisplayHeight(); i++){
+ *wx_pixels++ = cairo_pixels[2];
+ *wx_pixels++ = cairo_pixels[1];
+ *wx_pixels++ = cairo_pixels[0];
+ cairo_pixels += 4;
+ }
+ cairo_destroy(cr);
+ cairo_surface_destroy(cs);
+ cairo_surface_destroy(output_surface);
}
int TestPanel::getZoom() const {
« no previous file with comments | « configure.ac ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld