tari

CL PNG filter

Aug 13th, 2010
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.65 KB | None | 0 0
  1. //Image border color must be 0x00000000
  2. //Filtered result is 32bpp RGBA.
  3. __kernel void png_filterRow(__global __read_only image2d_t raw,
  4.                             __global uchar *filtered,
  5.                             __local uint4 *rcache,
  6.                             __local uint4 *ucache) {
  7.     //Image sampler for reading raw
  8.     const sampler_t ss = CLK_NORMALIZED_COORDS_FALSE |  //Use pixel coords
  9.                          CLK_ADDRESS_CLAMP |            //Clamp to black
  10.                          CLK_FILTER_NEAREST;            //No interpolation
  11.    
  12.     //One work-group per image row, one worker per pixel
  13.     size_t row = get_group_id(0);
  14.     size_t rowlen = get_image_width(raw);
  15.     size_t col = get_local_id(0);
  16.    
  17.     //Do something to figure which filter type to use for the row
  18.     uchar filter_type = PNG_FILTER_PAETH;
  19.     //Assuming 24-bit color, keeping the int4 to avoid saturating filters
  20.     uint4 pixel = read_imageui(raw, ss, (int2)(col, row));
  21.     //TODO: filtered values are probably signed.  Verify that & fix
  22.    
  23.     //Cache adjacent pixels in __local if useful for the filter
  24.     if (filter_type != PNG_FILTER_NONE) {
  25.         //Needs adjusting if > 1 workgroup per row
  26.         //TODO: check image addressing- is (0,0) upper or lower left?
  27.         rcache[0] = read_imageui(raw, ss, (int2)(-1,row));
  28.         rcache[col+1] = pixel;
  29.         if (filter_type != PNG_FILTER_SUB) {
  30.             //Up, Average and Paeth all look at preceding row too, cache that
  31.             ucache[0] = read_imageui(raw, ss, (int2)(-1, row-1));
  32.             ucache[col+1] = read_imageui(raw, ss, (int2)(col, row-1)
  33.         }
  34.         barrier(CLK_LOCAL_MEM_FENCE);       //Sync {u,r}cache
  35.     }
  36.    
  37.     uint4 predicted;
  38.     switch (filter_type) {
  39.         case PNG_FILTER_NONE:
  40.             predicted = 0;
  41.             break;
  42.         case PNG_FILTER_SUB:
  43.             predicted = rcache[col];
  44.             break;
  45.         case PNG_FILTER_UP:
  46.             predicted = ucache[col+1];
  47.             break;
  48.         case PNG_FILTER_AVERAGE:
  49.             predicted = (rcache[col] + ucache[col+1]) / 2;
  50.             break;
  51.         case PNG_FILTER_PAETH:
  52.             uint4 a = rcache[col], b = ucache[col+1], c = ucache[col];
  53.             uint4 p = a + b - c;
  54.             //Hopefully minmag will shuffle members to select the nearest
  55.             //component from each vector, else need nasty logic.
  56.             predicted = minmag(a-p, b-p);
  57.             predicted = minmag(predicted, c-p);
  58.             break;
  59.     }
  60.    
  61.     //Write out filtered pixel
  62.     pixel -= predicted;
  63.     uchar4 bytes = convert_uchar4(pixel);
  64.     vstore4(bytes, (row * rowlen) + col, filtered);
  65. }
Add Comment
Please, Sign In to add comment