Example #1
0
Ybuffer*
Ybuffer_init(int initiallength)
{
  char *data;
  Ybuffer *membuf;

  membuf = (Ybuffer*) Ymem_malloc(sizeof(Ybuffer));
  if (membuf == NULL) {
    return NULL;
  }

  if (initiallength <= 0) {
    membuf->data = NULL;
    membuf->datalen = 0;
    membuf->dataincr = 64;
  } else {
      data = (char*) Ymem_malloc(initiallength);
    if (data == NULL) {
      Ymem_free(membuf);
      return NULL;
    }
    membuf->data = data;
    membuf->datalen = initiallength;
    membuf->dataincr = initiallength;
  }

  membuf->pos = 0;
  membuf->status = YBUFFER_STATUS_OK;

  return membuf;
}
Example #2
0
/* Preload data from file */
char*
LoadDataFromFile(const char *filename, size_t *length)
{
  int fd;
  struct stat statbuf;
  size_t flen = 0;
  char *fbase = NULL;
  char *p;
  size_t rem;
  ssize_t readlen;

  fd = open(filename, O_RDONLY);
  if (fd == -1) {
    return NULL;
  }

  /* Load image content in memory, to get rid of any risk of
   I/O and cache effect during benchmark */
  fstat(fd, &statbuf);

  flen = statbuf.st_size;
  if (flen == 0) {
    close(fd);
    return NULL;
  }

  fbase = (char*) Ymem_malloc(flen);
  if (fbase == NULL) {
    close(fd);
    return NULL;
  }

  p = fbase;
  rem = flen;
  while (rem > 0) {
    readlen = read(fd, p, rem);
    if (readlen < 0) {
      free(fbase);
      close(fd);
      return NULL;
    }

    p += readlen;
    rem -= readlen;
  }
  close(fd);

  if (length != NULL) {
    *length = flen;
  }

  return fbase;
}
Example #3
0
static boolean
APP1_handler (j_decompress_ptr cinfo) {
  int length;
  int i;
  unsigned char *data = NULL;

  if (cinfo == NULL) {
    return FALSE;
  }

  length = jpeg_getc(cinfo) << 8;
  length += jpeg_getc(cinfo);
  if (length < 2) {
    return FALSE;
  }
  length -= 2;
  
  /* Read marker data in memory. Also get sure buffer is null terminated
     Null terminates buffer to make it printable for debugging */
  data = Ymem_malloc(length + 1);
  if (data == NULL) {
    return FALSE;
  }
  for (i = 0; i < length; i++) {
    data[i] = (unsigned char) jpeg_getc(cinfo);
  }
  data[length] = '\0';

  int l = strlen(XMP_MARKER);
  if (length >= l + 1 && memcmp(data, XMP_MARKER, l) == 0 && data[l] == '\0') {
    VbitmapXmp xmp;
    Vbitmap *vbitmap = (Vbitmap*) cinfo->client_data;
    char *xmpbuf = (char*) (data + l + 1);
    int xmplen = length - (l + 1);

    /* Parse XML data */
    if (parseXMP(&xmp, xmpbuf, xmplen) == YMAGINE_OK) {
      if (vbitmap != NULL) {
        VbitmapSetXMP(vbitmap, &xmp);
      }
    }
  }

  Ymem_free(data);

  return TRUE;
}
Example #4
0
int
VbitmapRegionSelect(Vbitmap *vbitmap, int xmin, int ymin, int width, int height)
{
    if (vbitmap == NULL) return YMAGINE_ERROR;
    if (vbitmap->region == NULL) {
        vbitmap->region = Ymem_malloc(sizeof(Vrect));
    }
    // Checking again for NULL in case Ymem_malloc failed
    if (vbitmap->region != NULL) {
        vbitmap->region->x = xmin;
        vbitmap->region->y = ymin;
        vbitmap->region->width = (width < 0) ? 0 : width;
        vbitmap->region->height = (height < 0) ? 0 : height;
        return YMAGINE_OK;
    }
    return YMAGINE_ERROR;
}
Example #5
0
int
getThemeColors(Vbitmap *vbitmap, int ncol, int *colors, int *scores)
{
  int ncolors = 0;
  int i;

  if (vbitmap == NULL || ncol <= 0) {
    return 0;
  }

  Vcolor *vcolors = Ymem_malloc(ncol * sizeof(Vcolor));

  if (vcolors != NULL) {
    ncolors = quantizeWithOptions(vbitmap, ncol, vcolors, scores,
                                  YMAGINE_THEME_SATURATION);
    for (i = 0; i < ncolors; i++) {
	    colors[i] = RGBA(vcolors[i].red, vcolors[i].green,
                       vcolors[i].blue, vcolors[i].alpha);
    }
    Ymem_free(vcolors);
  }

  return ncolors;
}
Example #6
0
static int
TransformerPrepare(Transformer *transformer)
{
  int pitch;
  void *tmpptr;
  unsigned char* alignedptr = NULL;
  int nlines;
  int alignment = 8;
  int i;
  YBOOL convolution;

  if (transformer == NULL) {
    return YMAGINE_ERROR;
  }

  convolution = transformer->convmode != TRANSFORMER_CONVOLUTION_NONE;

  if (transformer->srcrect.width <= 0 || transformer->srcrect.height <= 0) {
    /* No region set by caller, default to full input */
    transformer->srcrect.x = 0;
    transformer->srcrect.y = 0;
    transformer->srcrect.width = transformer->srcw;
    transformer->srcrect.height = transformer->srch;
  }

  transformer->destrect.x = 0;
  transformer->destrect.y = 0;
  transformer->destrect.width = transformer->destw;
  transformer->destrect.height = transformer->desth;

  /* Intersect source region with actual window */
  if (transformer->srcrect.width < 0) {
    transformer->srcrect.width = 0;
  }
  if (transformer->srcrect.height < 0) {
    transformer->srcrect.height = 0;
  }
  if (transformer->srcrect.x < 0) {
    transformer->srcrect.width += transformer->srcrect.x;
    transformer->srcrect.x = 0;
  }
  if (transformer->srcrect.y < 0) {
    transformer->srcrect.height += transformer->srcrect.y;
    transformer->srcrect.y = 0;
  }
  if (transformer->srcrect.x + transformer->srcrect.width > transformer->srcw) {
    transformer->srcrect.width = transformer->srcw - transformer->srcrect.x;
  }
  if (transformer->srcrect.y + transformer->srcrect.height > transformer->srch) {
    transformer->srcrect.height = transformer->srch - transformer->srcrect.y;
  }

  if (transformer->srcrect.x >= transformer->srcw ||
      transformer->srcrect.y >= transformer->srch ||
      transformer->srcrect.width <= 0 ||
      transformer->srcrect.height <= 0 ||
      transformer->srcrect.x + transformer->srcrect.width < 0 ||
      transformer->srcrect.y + transformer->srcrect.height < 0) {
    /* Empty region */
    transformer->srcrect.x = 0;
    transformer->srcrect.y = 0;
    transformer->srcrect.width = 0;
    transformer->srcrect.height = 0;
  }

  transformer->srcbpp = colorBpp(transformer->srcmode);
  transformer->destbpp = colorBpp(transformer->destmode);

  /* Allocate a working buffer large enough to contain at least 2 full lines
   at the output resolution, plus one working line */
  nlines = 3;

  if (convolution) {
    /* allocates 3 more line convolution buffer for 3x3 convolution.
       we may get better cache performance when convolution buffer is allocated
       together with working buffer (closer to working buffer in memory). */
    nlines += 3;
  }

  pitch = transformer->destw * transformer->destbpp;
  if (pitch % alignment) {
    pitch += alignment - (pitch % alignment);
  }

  if (pitch > 0) {
    tmpptr = Ymem_malloc_aligned(alignment, pitch * nlines, (void**) &alignedptr);
    if (tmpptr == NULL) {
      return YMAGINE_ERROR;
    }

    transformer->destbuf = tmpptr;
    transformer->destaligned = alignedptr;
    transformer->destpitch = pitch;

    /* Lines */
    transformer->scaledbuf = alignedptr + transformer->destpitch * 0;
    transformer->curbuf = alignedptr + transformer->destpitch * 1;
    transformer->tmpbuf = alignedptr + transformer->destpitch * 2;

    if (convolution) {
      transformer->convcprev = alignedptr + transformer->destpitch * 3;
      transformer->convcur = alignedptr + transformer->destpitch * 4;
      transformer->convnext = alignedptr + transformer->destpitch * 5;
    }
  }

  /* Pre-compute offset table for line scaling */
  if (transformer->destrect.width != transformer->srcrect.width && transformer->destrect.width > 0) {
    transformer->bltmap = (int*) Ymem_malloc(transformer->destrect.width * sizeof(int));
    if (transformer->bltmap != NULL) {
      bltLinePrepare(transformer->bltmap, transformer->destrect.width, transformer->srcrect.width);
    }
  }

  if (transformer->statsmode > 0) {
    if (transformer->srcrect.width > 0 && transformer->srcrect.height > 0) {
      int nchannels;

      if (transformer->srcmode == VBITMAP_COLOR_GRAYSCALE) {
        nchannels = 1;
      } else if (transformer->srcmode == VBITMAP_COLOR_RGB) {
        nchannels = 3;
      } else if (transformer->srcmode == VBITMAP_COLOR_RGBA) {
        nchannels = 4;
      } else {
        nchannels = 0;
      }

      if (nchannels > 0) {
        transformer->statsbuf = Ymem_malloc(256 * nchannels * sizeof(int));
        if (transformer->statsbuf != NULL) {
          transformer->histlum = transformer->statsbuf;
          for (i = 0; i < 256; i++) {
            transformer->histlum[i] = 0;
          }

          if (nchannels >= 3) {
            transformer->histr = transformer->statsbuf + 256 * 1;
            transformer->histg = transformer->statsbuf + 256 * 2;
            transformer->histb = transformer->statsbuf + 256 * 3;

            for (i = 0; i < 256; i++) {
              transformer->histr[i] = 0;
              transformer->histg[i] = 0;
              transformer->histb[i] = 0;
            }
          }
        }
        transformer->statscount = 0;
      }
    }
  }

  return YMAGINE_OK;
}
Example #7
0
/* Methods */
int
VbitmapResize(Vbitmap *vbitmap, int width, int height)
{
  if (vbitmap == NULL) {
    return YMAGINE_ERROR;
  }

  if (width <= 0 || height <= 0) {
    return YMAGINE_ERROR;
  }

  if (width == vbitmap->width && height == vbitmap->height) {
    /* Size not changed, ignore */
    return YMAGINE_OK;
  }

  if (vbitmap->bitmaptype == VBITMAP_NONE) {
    vbitmap->width = width;
    vbitmap->height = height;

    return YMAGINE_OK;
  }

  if (vbitmap->bitmaptype == VBITMAP_ANDROID) {
    AndroidBitmapInfo bitmapinfo;
    jobject jbitmap;
    jobject jbitmapref;
    int ret;

    JNIEnv *jenv = getEnv(vbitmap);
    if (jenv == NULL) {
      return YMAGINE_ERROR;
    }

    jbitmap = createAndroidBitmap(jenv, width, height);
    if (jbitmap == NULL) {
      return YMAGINE_ERROR;
    }

    ret = AndroidBitmap_getInfo(jenv, jbitmap, &bitmapinfo);
    if (ret < 0 ||
        bitmapinfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888 ||
        bitmapinfo.width != width || bitmapinfo.height != height) {
      return YMAGINE_ERROR;
    }

    jbitmapref = (*jenv)->NewGlobalRef(jenv, jbitmap);
    if (jbitmapref == NULL) {
      return YMAGINE_ERROR;
    }

    /* Replace Bitmap */
    if (vbitmap->jbitmap != NULL) {
      if (vbitmap->jkeepref) {
        (*jenv)->DeleteGlobalRef(jenv, vbitmap->jbitmap);
        vbitmap->jkeepref = 0;
      }
      vbitmap->jbitmap = NULL;
    }

#if VBITMAP_ENABLE_GLOBAL_REF
      vbitmap->jbitmap = jbitmapref;
      vbitmap->jkeepref = 1;
#else
      vbitmap->jbitmap = jbitmap;
      vbitmap->jkeepref = 0;
      (*jenv)->DeleteGlobalRef(jenv, jbitmapref);
#endif

    vbitmap->width = bitmapinfo.width;
    vbitmap->height = bitmapinfo.height;
    vbitmap->pitch = bitmapinfo.stride;

    return YMAGINE_OK;
  }

  if (vbitmap->bitmaptype == VBITMAP_MEMORY) {
    int bpp = colorBpp(VbitmapColormode(vbitmap));
    int pitch = width * bpp;
    unsigned char *pixels = NULL;

    if (pitch > 0) {
      pixels = Ymem_malloc(pitch * height);
    }
    if (pixels == NULL) {
      return YMAGINE_ERROR;
    }

    if (vbitmap->pixels != NULL) {
      Ymem_free(vbitmap->pixels);
    }

    vbitmap->pixels = pixels;
    vbitmap->width = width;
    vbitmap->height = height;
    vbitmap->pitch = pitch;

    return YMAGINE_OK;
  }

  if (vbitmap->bitmaptype == VBITMAP_STATIC) {
    /* Can't resize a static bitmap */
    return YMAGINE_ERROR;
  }

  return YMAGINE_ERROR;
}
Example #8
0
/*
 A fast, yet not gaussian blurring algorithm.

 To approximate gaussian blur accurately, one can call blurSuperfast with
 a small radius and higher number of iterations
 */
int
Ymagine_blurSuperfast(unsigned char *pix,
                      int w, int h, int pitch,
                      int colormode,
                      int radius, int niter)
{
  unsigned char *dv = NULL;
  int *vbuf = NULL;
  unsigned char *rgba = NULL;
  int wm, hm;
  int wh;
  int div;
  unsigned char *r, *g, *b, *a;
  int rsum, gsum, bsum, asum;;
  int x, y;
  int i, n;
  int p, p1, p2;
  int yi, zi, yw;
  int maxwh;
  int *vmin;
  int *vmax;
  int alpha = 255;
  int alpha2 = 255;
  int rc = YMAGINE_ERROR;
  int bpp;
  int roffset, goffset, boffset, aoffset;
  int premultiply = 0;

  if (radius <= 0 || niter <= 0) {
    return YMAGINE_OK;
  }
  if (w <= 0 || h <= 0) {
    return YMAGINE_OK;
  }

  switch (colormode) {
  case VBITMAP_COLOR_RGBA:
    bpp = 4;
    roffset = 0;
    goffset = 1;
    boffset = 2;
    aoffset = 3;
    premultiply = 0;
    break;
  case VBITMAP_COLOR_rgbA:
    bpp = 4;
    roffset = 0;
    goffset = 1;
    boffset = 2;
    aoffset = 3;
    premultiply = 1;
    break;
  case VBITMAP_COLOR_ARGB:
    bpp = 4;
    roffset = 1;
    goffset = 2;
    boffset = 3;
    aoffset = 0;
    premultiply = 0;
    break;
  case VBITMAP_COLOR_Argb:
    bpp = 4;
    roffset = 1;
    goffset = 2;
    boffset = 3;
    aoffset = 0;
    premultiply = 1;
    break;
  case VBITMAP_COLOR_RGB:
    bpp = 3;
    roffset = 0;
    goffset = 1;
    boffset = 2;
    aoffset = -1;
    premultiply = 0;
    break;
  default:
    return YMAGINE_ERROR;
  }

  maxwh = MAX(w, h);
  wm = w - 1;
  hm = h - 1;
  wh = w * h;
  div = radius + radius + 1;

  /* TODO: dont recalculate if calling multiple time with same radius */
  dv = (unsigned char*) Ymem_malloc(256*div*sizeof(dv[0]));
  if (dv == NULL) {
    goto cleanup;
  }
  for (i = 0 ; i < 256 * div; i++) {
    dv[i] = (i / div);
  }

  vbuf = (int*) Ymem_malloc(maxwh * sizeof(vbuf[0]) * 2);
  if (vbuf == NULL) {
    goto cleanup;
  }
  rgba = Ymem_malloc(wh * 4);
  if (rgba == NULL) {
    goto cleanup;
  }

  r = rgba;
  g = r + wh;
  b = g + wh;
  a = b + wh;

  vmin = vbuf;
  vmax = vbuf + maxwh;

  for (n = 0; n < niter; n++) {
    yw = 0;

    /* Vertical pass */
    for (y = 0; y < h; y++) {
      rsum = 0;
      gsum = 0;
      bsum = 0;
      asum = 0;

      yi = y * pitch;
      zi = y * w;

      for (i = -radius; i <= radius; i++) {
        p = yi + (MIN(wm, MAX(i,0)) * bpp);
        if (aoffset >= 0) {
          alpha = pix[p + aoffset];
        }

        if (alpha == 255 || premultiply) {
          rsum += pix[p + roffset];
          gsum += pix[p + goffset];
          bsum += pix[p + boffset];
        } else if (alpha != 0) {
          rsum += (pix[p + roffset] * alpha) / 255;
          gsum += (pix[p + goffset] * alpha) / 255;
          bsum += (pix[p + boffset] * alpha) / 255;
        }
        asum += alpha;
      }

      for (x = 0; x < w; x++) {
        r[zi] = dv[rsum];
        g[zi] = dv[gsum];
        b[zi] = dv[bsum];
        a[zi] = dv[asum];

        if (y == 0) {
          vmin[x] = MIN(x+radius+1, wm);
          vmax[x] = MAX(x-radius, 0);
        }
        p1 = yw + (vmin[x] * bpp);
        p2 = yw + (vmax[x] * bpp);

        if (aoffset >= 0) {
          alpha = pix[p1 + aoffset];
          alpha2 = pix[p2 + aoffset];
        }
        if ((alpha == 255 && alpha2 == 255) || premultiply) {
          rsum += pix[p1 + roffset] - pix[p2 + roffset];
          gsum += pix[p1 + goffset] - pix[p2 + goffset];
          bsum += pix[p1 + boffset] - pix[p2 + boffset];
        } else {
          rsum += (pix[p1 + roffset] * alpha) / 255 - (pix[p2 + roffset] * alpha2) / 255;
          gsum += (pix[p1 + goffset] * alpha) / 255 - (pix[p2 + goffset] * alpha2) / 255;
          bsum += (pix[p1 + boffset] * alpha) / 255 - (pix[p2 + boffset] * alpha2) / 255;
        }
        asum += alpha - alpha2;

        zi++;
      }

      yw += pitch;
    }

    /* Horizontal pass */
    for (x = 0; x < w; x++) {
      rsum = 0;
      gsum = 0;
      bsum = 0;
      asum = 0;

      for (i = -radius; i <= radius; i++) {
        yi = MIN(MAX(0,i),hm) * w + x;
        rsum += r[yi];
        gsum += g[yi];
        bsum += b[yi];
        asum += a[yi];
      }

      yi = x * bpp;
      for (y = 0; y < h; y++) {
        pix[yi + roffset] = dv[rsum];
        pix[yi + goffset] = dv[gsum];
        pix[yi + boffset] = dv[bsum];
        if (aoffset >= 0) {
          pix[yi + aoffset] = dv[asum];
        }

        if (x == 0) {
          vmin[y] = MIN(y+radius+1, hm)*w;
          vmax[y] = MAX(y-radius, 0)*w;
        }
        p1 = x + vmin[y];
        p2 = x + vmax[y];

        if (aoffset >= 0) {
          alpha = a[p1];
          alpha2 = a[p2];
        }

        rsum += r[p1] - r[p2];
        gsum += g[p1] - g[p2];
        bsum += b[p1] - b[p2];
        if (alpha != alpha2) {
          asum += alpha - alpha2;
        }

        yi += pitch;
      }
    }
  }

  rc = YMAGINE_OK;

cleanup:
  if (rgba != NULL) {
    Ymem_free(rgba);
    rgba = NULL;
  }
  if (vbuf != NULL) {
    Ymem_free(vbuf);
    vbuf = NULL;
  }
  if (dv != NULL) {
    Ymem_free(dv);
    dv = NULL;
  }

  return rc;
}