Ejemplo n.º 1
0
int
VbitmapBpp(Vbitmap *vbitmap)
{
  if (vbitmap == NULL) {
    return 0;
  }

  return colorBpp(VbitmapColormode(vbitmap));
}
Ejemplo n.º 2
0
YOPTIMIZE_SPEED int
YmagineMergeLine(unsigned char *destpixels, int destmode, int destweight,
                 const unsigned char *srcpixels, int srcmode, int srcweight,
                 int width)
{
  int bpp;
  int rc = YMAGINE_ERROR;

  if (destweight < 0 || srcweight < 0 ||
      destpixels == NULL || srcpixels == NULL) {
    return rc;
  }

  if (destmode != srcmode) {
    /* now only supports merge lines with same color mode */
    return rc;
  }

  bpp = colorBpp(destmode);

  if (srcweight == 0) {
    /* Nothing to do */
    rc = YMAGINE_OK;
  } else if (destweight == 0) {
    memcpy(destpixels, srcpixels, width * bpp * sizeof(unsigned char));
    rc = YMAGINE_OK;
  } else {
    switch (destmode) {
    case VBITMAP_COLOR_GRAYSCALE:
      rc = mergeLine(destpixels, destweight, srcpixels, srcweight, width, 1, -1, 0);
      break;
    case VBITMAP_COLOR_RGB:
      rc = mergeLine(destpixels, destweight, srcpixels, srcweight, width, 3, -1, 0);
      break;
    case VBITMAP_COLOR_RGBA:
      rc = mergeLine(destpixels, destweight, srcpixels, srcweight, width, 4, 3, 0);
      break;
    case VBITMAP_COLOR_rgbA:
      rc = mergeLine(destpixels, destweight, srcpixels, srcweight, width, 4, 3, 1);
      break;
    case VBITMAP_COLOR_ARGB:
      rc = mergeLine(destpixels, destweight, srcpixels, srcweight, width, 4, 0, 0);
      break;
    case VBITMAP_COLOR_Argb:
      rc = mergeLine(destpixels, destweight, srcpixels, srcweight, width, 4, 0, 1);
      break;
    default:
      rc = mergeLine(destpixels, destweight, srcpixels, srcweight, width, bpp, -1, 0);
      break;
    }
  }

  return rc;
}
Ejemplo n.º 3
0
int
TransformerSetBitmap(Transformer *transformer, Vbitmap *vbitmap,
                     int offsetx, int offsety)
{
  int rc = YMAGINE_OK;

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

  if (transformer->obitmap != NULL) {
    VbitmapUnlock(transformer->obitmap);
  }

  if (vbitmap != NULL) {
    rc = VbitmapLock(vbitmap);
    if (rc != YMAGINE_OK) {
      vbitmap = NULL;
    }
  }

  transformer->obitmap = vbitmap;

  if (vbitmap == NULL) {
    transformer->obitmap = NULL;
    transformer->obuffer = NULL;
    transformer->owidth = 0;
    transformer->oheight = 0;
    transformer->opitch = 0;
    transformer->omode = VBITMAP_COLOR_RGBA;
    transformer->obpp = 0;
    transformer->offsetx = 0;
    transformer->offsety = 0;
  } else {
    transformer->obitmap = vbitmap;
    transformer->obuffer = VbitmapBuffer(vbitmap);
    transformer->owidth = VbitmapWidth(vbitmap);
    transformer->oheight = VbitmapHeight(vbitmap);
    transformer->opitch = VbitmapPitch(vbitmap);
    transformer->omode = VbitmapColormode(vbitmap);
    transformer->obpp = colorBpp(transformer->omode);
    transformer->offsetx = offsetx;
    transformer->offsety = offsety;
  }

  return rc;
}
Ejemplo n.º 4
0
Transformer*
TransformerCreate()
{
  Transformer* transformer;

  transformer = (Transformer*) yobject_create(sizeof(Transformer),
                                            TransformerReleaseCallback);
  if (transformer == NULL) {
    return NULL;
  }

  transformer->srcw = 0;
  transformer->srch = 0;

  transformer->destw = 0;
  transformer->desth = 0;

  transformer->nexty = 0;
  transformer->nextyf = YFIXED_ZERO;

  transformer->cury = transformer->nexty;
  transformer->curyf = transformer->nextyf;

  transformer->desty = -1;
  transformer->stashedweight = YFIXED_ZERO;

  transformer->srcrect.x = 0;
  transformer->srcrect.y = 0;
  transformer->srcrect.width = 0;
  transformer->srcrect.height = 0;

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

  /* 3x3 convolution */
  transformer->convmode = TRANSFORMER_CONVOLUTION_NONE;
  transformer->convlinecount = 0;
  transformer->convcprev = NULL;
  transformer->convcur = NULL;
  transformer->convnext = NULL;

  /* transformer state */
  transformer->srcline = -1;
  transformer->srcmode = VBITMAP_COLOR_RGBA;
  transformer->srcbpp = colorBpp(transformer->srcmode);

  transformer->destmode = VBITMAP_COLOR_RGBA;
  transformer->destbpp = colorBpp(transformer->destmode);
  transformer->destpitch = 0;

  transformer->destbuf = NULL;
  transformer->destaligned = NULL;

  transformer->statsmode = 0;
  transformer->statscount = 0;
  transformer->statsbuf = NULL;
  transformer->histr = NULL;
  transformer->histg = NULL;
  transformer->histb = NULL;
  transformer->histlum = NULL;

  transformer->scaledbuf = NULL;
  transformer->curbuf = NULL;
  transformer->tmpbuf = NULL;

  transformer->bltmap = NULL;

  transformer->obitmap = NULL;
  TransformerSetBitmap(transformer, NULL, 0, 0);

  transformer->shader = NULL;
  transformer->sharpen = 0.0f;

  /* Transformer writer callback */
  transformer->writer = NULL;
  transformer->writerdata = NULL;

  return transformer;
}
Ejemplo n.º 5
0
static YOPTIMIZE_SPEED int
bltLineExt(unsigned char *opixels, int owidth, int oformat,
           const unsigned char *ipixels, int iwidth, int iformat,
           int *map)
{
  int ibpp, obpp;
  int ialphaidx;
  int oalphaidx;

  if (owidth <= 0) {
    return YMAGINE_OK;
  }
  if (iwidth <= 0) {
    return YMAGINE_ERROR;
  }

  ibpp = colorBpp(iformat);
  obpp = colorBpp(oformat);

  if (owidth == iwidth) {
    if (iformat == oformat) {
      /* Neither scaling or color transformation */
      memcpy(opixels, ipixels, owidth * obpp);
      return YMAGINE_OK;
    }

    /* No scaling but color conversion */
    if (iformat == VBITMAP_COLOR_RGB) {
      if (oformat == VBITMAP_COLOR_rgbA || oformat == VBITMAP_COLOR_RGBA) {
        RGBtoRGBA(opixels, ipixels, iwidth);
        if (oformat == VBITMAP_COLOR_rgbA) {
          premultiplyRGBA(opixels, owidth, obpp);
        }
        return YMAGINE_OK;
      }
      if (oformat == VBITMAP_COLOR_Argb || oformat == VBITMAP_COLOR_ARGB) {
        RGBtoARGB(opixels, ipixels, iwidth);
        if (oformat == VBITMAP_COLOR_Argb) {
          premultiplyARGB(opixels, owidth, obpp);
        }
        return YMAGINE_OK;
      }
    }
    if (iformat == VBITMAP_COLOR_RGBA) {
      if (oformat == VBITMAP_COLOR_ARGB) {
        memcpy(opixels, ipixels, owidth * obpp);
        RGBAtoARGB(opixels, owidth, obpp);
        return YMAGINE_OK;
      }
      if (oformat == VBITMAP_COLOR_Argb) {
        memcpy(opixels, ipixels, owidth * obpp);
        RGBAtoARGB(opixels, owidth, obpp);
        premultiplyARGB(opixels, owidth, obpp);
        return YMAGINE_OK;
      }
      if (oformat == VBITMAP_COLOR_rgbA) {
        memcpy(opixels, ipixels, owidth * obpp);
        premultiplyRGBA(opixels, owidth, obpp);
        return YMAGINE_OK;
      }
    }
  }

  if (iformat != oformat) {
    int valid = 0;

    /* Only support a limited set of colorspace conversions */
    if (oformat == VBITMAP_COLOR_RGBA|| oformat == VBITMAP_COLOR_ARGB ||
        oformat == VBITMAP_COLOR_rgbA || oformat == VBITMAP_COLOR_Argb ||
        oformat == VBITMAP_COLOR_RGB) {
      if (iformat == VBITMAP_COLOR_RGBA|| iformat == VBITMAP_COLOR_ARGB ||
          iformat == VBITMAP_COLOR_rgbA || iformat == VBITMAP_COLOR_Argb ||
          iformat == VBITMAP_COLOR_RGB || iformat == VBITMAP_COLOR_CMYK) {
        valid = 1;
      }
    }

    if (!valid) {
      return YMAGINE_ERROR;
    }
  }

  if (iformat == VBITMAP_COLOR_RGB && oformat == VBITMAP_COLOR_RGBA) {
    scaleLine(opixels, owidth, VBITMAP_COLOR_RGBA, 4, 3,
              ipixels, iwidth, VBITMAP_COLOR_RGB, 3, -1,
              map);
  } else if (iformat == VBITMAP_COLOR_RGB && oformat == VBITMAP_COLOR_rgbA) {
    scaleLine(opixels, owidth, VBITMAP_COLOR_rgbA, 4, 3,
              ipixels, iwidth, VBITMAP_COLOR_RGB, 3, -1,
              map);
  } else if (iformat == VBITMAP_COLOR_RGBA && oformat == VBITMAP_COLOR_RGBA) {
    scaleLine(opixels, owidth, VBITMAP_COLOR_RGBA, 4, 3,
              ipixels, iwidth, VBITMAP_COLOR_RGBA, 4, 3,
              map);
  } else if (iformat == VBITMAP_COLOR_RGBA && oformat == VBITMAP_COLOR_rgbA) {
    scaleLine(opixels, owidth, VBITMAP_COLOR_RGBA, 4, 3,
              ipixels, iwidth, VBITMAP_COLOR_rgbA, 4, 3,
              map);
  } else {
    if (iformat == VBITMAP_COLOR_RGBA) {
      ialphaidx = 3;
    } else {
      ialphaidx = -1;
    }
    if (oformat == VBITMAP_COLOR_RGBA) {
      oalphaidx = 3;
    } else {
      oalphaidx = -1;
    }
    scaleLine(opixels, owidth, oformat, obpp, oalphaidx,
              ipixels, iwidth, iformat, ibpp, ialphaidx,
              map);
  }

  return YMAGINE_OK;
}
Ejemplo n.º 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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 8
0
int
Vbitmap_sobel(Vbitmap *outbitmap, Vbitmap *vbitmap)
{
  int width;
  int height;
  int pitch;
  int bpp;
  unsigned char *pixels;

  int owidth;
  int oheight;
  int opitch;
  int obpp;
  unsigned char *opixels;

  int i, j;

  unsigned char *inp;
  unsigned char *outp;

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

  if (VbitmapLock(vbitmap) >= 0) {
    pixels = VbitmapBuffer(vbitmap);
    width = VbitmapWidth(vbitmap);
    height = VbitmapHeight(vbitmap);
    pitch = VbitmapPitch(vbitmap);
    bpp = colorBpp(VbitmapColormode(vbitmap));

    if (VbitmapLock(outbitmap) >= 0) {
      opixels = VbitmapBuffer(outbitmap);
      owidth = VbitmapWidth(outbitmap);
      oheight = VbitmapHeight(outbitmap);
      opitch = VbitmapPitch(outbitmap);
      obpp = colorBpp(VbitmapColormode(outbitmap));

      if (width != owidth || height != oheight) {
        VbitmapUnlock(outbitmap);
        if (VbitmapResize(outbitmap, width, height) == YMAGINE_OK) {
          if (VbitmapLock(outbitmap) < 0) {
            VbitmapUnlock(vbitmap);
            return YMAGINE_ERROR;
          }

          opixels = VbitmapBuffer(outbitmap);
          owidth = VbitmapWidth(outbitmap);
          oheight = VbitmapHeight(outbitmap);
          opitch = VbitmapPitch(outbitmap);
          obpp = colorBpp(VbitmapColormode(outbitmap));
        }
      }

      if (width == owidth && height == oheight && bpp >= 3) {
        for (j = 0; j < height; j++) {
          inp = pixels + pitch * j;
          outp = opixels + opitch * j;

          outp[0] = EnergySobel(inp, bpp, pitch, 0, j, width, height);
          outp += obpp;
          inp += bpp;

          if (j != 0 && j != height-1) {
            for (i = 1; i < width - 1; i++) {
              outp[0] = EnergySobelFast(inp, bpp, pitch);
              outp += obpp;
              inp += bpp;
            }
          } else {
            for (i = 1; i < width - 1; i++) {
              outp[0] = EnergySobel(inp, bpp, pitch, i, j, width, height);
              outp += obpp;
              inp += bpp;
            }
          }

          outp[0] = EnergySobel(inp, bpp, pitch, width - 1, j, width, height);
        }

        if (obpp >= 3) {
          for (j = 0; j < height; j++) {
            outp = opixels + opitch * j;
            for (i = 0; i < width; i++) {              
              outp[1] = outp[0];
              outp[2] = outp[0];
              if (obpp == 4) {                
                outp[0] = 0xff;
              }

              outp += obpp;
            }
          }
        }
      }

      VbitmapUnlock(outbitmap);
    }

    VbitmapUnlock(vbitmap);
  }

  return YMAGINE_OK;
}