Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

If it ain't Lisp, it's crap

Name: Anonymous 2012-06-24 22:04

Lisp

(defun png-defilter (g s)
  (let* ((w (gfx-w g))
         (h (gfx-h g))
         (c (gfx-c g))
         (s (cons s 0))
         (l (* w c))
         (d (cons (vec (* h l) u1) 0)))
    (dotimes (y h)
      (let* ((f (q s))
             (p  (cons (car d) (cdr d)))  ; prev pixel
             (u  (cons (car d) (- (cdr d) l)))  ; upper row
             (pu (cons (car u) (cdr u)))) ; upper row, prev pixel
        (when (and (= y 0) (case f ((2 3 4) t)))
          (setf p (cons (vec l u1) 0)))
        (case f
          (0 (dotimes (_ l)       (q d (q s)))) ; plaintext
          (1 (dotimes (_ c)       (q d (q s))) ; sub
             (dotimes (_ (- l c)) (q d (+ (q p) (q s)))))
          (2 (dotimes (_ l)       (q d (+ (q u) (q s))))) ; up
          (3 (dotimes (_ c)       (q d (+ (avg     0 (q u)) (q s)))) ; average
             (dotimes (_ (- l c)) (q d (+ (avg (q p) (q u)) (q s)))))
          (4 (dotimes (_ c)       (q d (+ (paeth     0 (q u)      0) (q s)))) ; paeth
             (dotimes (_ (- l c)) (q d (+ (paeth (q p) (q u) (q pu)) (q s)))))
          (otherwise (gfx-load-error "Invalid line filter (~a)" f)))))
    (setf (gfx-d g) (rgb-to-ints c 1 (car d)))))


C/C++

static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon,
                                 size_t bytewidth, unsigned char filterType, size_t length)
{
  /*
  For PNG filter method 0
  unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte,
  the filter works byte per byte (bytewidth = 1)
  precon is the previous unfiltered scanline, recon the result, scanline the current one
  the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead
  recon and scanline MAY be the same memory address! precon must be disjoint.
  */

  size_t i;
  switch(filterType)
  {
    case 0:
      for(i = 0; i < length; i++) recon[i] = scanline[i];
      break;
    case 1:
      for(i =         0; i < bytewidth; i++) recon[i] = scanline[i];
      for(i = bytewidth; i <    length; i++) recon[i] = scanline[i] + recon[i - bytewidth];
      break;
    case 2:
      if(precon)
      {
        for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i];
      }
      else
      {
        for(i = 0; i < length; i++) recon[i] = scanline[i];
      }
      break;
    case 3:
      if(precon)
      {
        for(i =         0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2;
        for(i = bytewidth; i <    length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2);
      }
      else
      {
        for(i =         0; i < bytewidth; i++) recon[i] = scanline[i];
        for(i = bytewidth; i <    length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2;
      }
      break;
    case 4:
      if(precon)
      {
        for(i = 0; i < bytewidth; i++)
        {
          recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/
        }
        for(i = bytewidth; i < length; i++)
        {
          recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
        }
      }
      else
      {
        for(i = 0; i < bytewidth; i++)
        {
          recon[i] = scanline[i];
        }
        for(i = bytewidth; i < length; i++)
        {
          /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/
          recon[i] = (scanline[i] + recon[i - bytewidth]);
        }
      }
      break;
    default: return 36; /*error: unexisting filter type given*/
  }
  return 0;
}

static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
{
  /*
  For PNG filter method 0
  this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times)
  out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline
  w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel
  in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes)
  */

  unsigned y;
  unsigned char* prevline = 0;

  /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
  size_t bytewidth = (bpp + 7) / 8;
  size_t linebytes = (w * bpp + 7) / 8;

  for(y = 0; y < h; y++)
  {
    size_t outindex = linebytes * y;
    size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
    unsigned char filterType = in[inindex];

    unsigned error = unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes);
    if(error) return error;

    prevline = &out[outindex];
  }

  return 0;
}

Name: Anonymous 2012-06-25 5:28

>>4
uses cons as a generic data structure
are there other way to create a pointer to array? I think compiler will optimize CONS on stack.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List