jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
changeset 2 90ce3da70b43
child 5506 202f599c92aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,541 @@
+/*
+ * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+/*
+ * FUNCTION
+ *      mlib_ImageCreateStruct   - create image data structure
+ *      mlib_ImageCreate         - create image data structure and allocate
+ *                                 memory for image data
+ *      mlib_ImageDelete         - delete image
+ *      mlib_ImageCreateSubimage - create sub-image
+ *
+ *      mlib_ImageCreateRowTable - create row starts pointer table
+ *      mlib_ImageDeleteRowTable - delete row starts pointer table
+ *
+ *      mlib_ImageSetPaddings    - set paddings for clipping box borders
+ *
+ *      mlib_ImageSetFormat      - set image format
+ *
+ * SYNOPSIS
+ *        mlib_image *mlib_ImageCreateStruct(mlib_type  type,
+ *                                           mlib_s32   channels,
+ *                                           mlib_s32   width,
+ *                                           mlib_s32   height,
+ *                                           mlib_s32   stride,
+ *                                           const void *data)
+ *
+ *        mlib_image *mlib_ImageCreate(mlib_type type,
+ *                                     mlib_s32  channels,
+ *                                     mlib_s32  width,
+ *                                     mlib_s32  height)
+ *
+ *        void mlib_ImageDelete(mlib_image *img)
+ *
+ *        mlib_image *mlib_ImageCreateSubimage(mlib_image *img,
+ *                                             mlib_s32   x,
+ *                                             mlib_s32   y,
+ *                                             mlib_s32   w,
+ *                                             mlib_s32   h)
+ *
+ *        void *mlib_ImageCreateRowTable(mlib_image *img)
+ *
+ *        void mlib_ImageDeleteRowTable(mlib_image *img)
+ *
+ *        mlib_status mlib_ImageSetPaddings(mlib_image *img,
+ *                                          mlib_u8    left,
+ *                                          mlib_u8    top,
+ *                                          mlib_u8    right,
+ *                                          mlib_u8    bottom)
+ *
+ *        mlib_status mlib_ImageSetFormat(mlib_image  *img,
+ *                                        mlib_format format)
+ * ARGUMENTS
+ *      img       pointer to image data structure
+ *      type      image data type, one of MLIB_BIT, MLIB_BYTE, MLIB_SHORT,
+ *                MLIB_USHORT, MLIB_INT, MLIB_FLOAT or MLIB_DOUBLE
+ *      channels  number of image channels
+ *      width     image width in pixels
+ *      height    image height in pixels
+ *      stride    linebytes( bytes to next row) of the image
+ *      data      pointer to image data allocated by user
+ *      x         x coordinate of the left border in the source image
+ *      y         y coordinate of the top border in the source image
+ *      w         width of the sub-image
+ *      h         height of the sub-image
+ *      left      clipping box left padding
+ *      top       clipping box top padding
+ *      right     clipping box right padding
+ *      bottom    clipping box bottom padding
+ *      format    image format
+ *
+ * DESCRIPTION
+ *      mlib_ImageCreateStruct() creates a mediaLib image data structure
+ *      using parameter supplied by user.
+ *
+ *      mlib_ImageCreate() creates a mediaLib image data structure and
+ *      allocates memory space for image data.
+ *
+ *      mlib_ImageDelete() deletes the mediaLib image data structure
+ *      and frees the memory space of the image data if it is allocated
+ *      through mlib_ImageCreate().
+ *
+ *      mlib_ImageCreateSubimage() creates a mediaLib image structure
+ *      for a sub-image based on a source image.
+ *
+ *      mlib_ImageCreateRowTable() creates row starts pointer table and
+ *      puts it into mlib_image->state field.
+ *
+ *      mlib_ImageDeleteRowTable() deletes row starts pointer table from
+ *      image and puts NULL into mlib_image->state field.
+ *
+ *      mlib_ImageSetPaddings() sets new values for the clipping box paddings
+ *
+ *      mlib_ImageSetFormat() sets new value for the image format
+ */
+
+#include <stdlib.h>
+#include "mlib_image.h"
+#include "mlib_ImageRowTable.h"
+#include "mlib_ImageCreate.h"
+
+/***************************************************************/
+mlib_image* mlib_ImageSet(mlib_image *image,
+                          mlib_type  type,
+                          mlib_s32   channels,
+                          mlib_s32   width,
+                          mlib_s32   height,
+                          mlib_s32   stride,
+                          const void *data)
+{
+  mlib_s32        wb;                /* width in bytes */
+  mlib_s32        mask;              /* mask for check of stride */
+
+  if (image == NULL) return NULL;
+
+/* for some ugly functions calling with incorrect parameters */
+  image -> type     = type;
+  image -> channels = channels;
+  image -> width    = width;
+  image -> height   = height;
+  image -> stride   = stride;
+  image -> data     = (void *)data;
+  image -> state    = NULL;
+  image -> format   = MLIB_FORMAT_UNKNOWN;
+
+  image -> paddings[0] = 0;
+  image -> paddings[1] = 0;
+  image -> paddings[2] = 0;
+  image -> paddings[3] = 0;
+
+  image -> bitoffset = 0;
+
+  if (width <= 0 || height <= 0 || channels < 1 || channels > 4) {
+    return NULL;
+  }
+
+/* Check if stride == width
+   * If it is then image can be treated as a 1-D vector
+ */
+  switch (type) {
+    case MLIB_DOUBLE:
+      wb = width * channels * 8;
+      mask = 7;
+      break;
+    case MLIB_FLOAT:
+    case MLIB_INT:
+      wb = width * channels * 4;
+      mask = 3;
+      break;
+    case MLIB_USHORT:
+    case MLIB_SHORT:
+      wb = width * channels * 2;
+      mask = 1;
+      break;
+    case MLIB_BYTE:
+      wb = width * channels;
+      mask = 0;
+      break;
+    case MLIB_BIT:
+      wb = (width * channels + 7) / 8;
+      mask = 0;
+      break;
+    default:
+      return NULL;
+  }
+
+  if (stride & mask) {
+    return NULL;
+  }
+
+  image -> flags    = ((width & 0xf) << 8);          /* set width field */
+  image -> flags   |= ((stride & 0xf) << 16);        /* set stride field */
+  image -> flags   |= ((height & 0xf) << 12);        /* set height field */
+  image -> flags   |= (mlib_addr)data & 0xff;
+  image -> flags   |= MLIB_IMAGE_USERALLOCATED;      /* user allocated data */
+
+  if ((stride != wb) ||
+      ((type == MLIB_BIT) && (stride * 8 != width * channels))) {
+    image -> flags |= MLIB_IMAGE_ONEDVECTOR;
+  }
+
+  image -> flags &= MLIB_IMAGE_ATTRIBUTESET;
+
+  return image;
+}
+
+/***************************************************************/
+mlib_image *mlib_ImageCreateStruct(mlib_type  type,
+                                   mlib_s32   channels,
+                                   mlib_s32   width,
+                                   mlib_s32   height,
+                                   mlib_s32   stride,
+                                   const void *data)
+{
+  mlib_image *image;
+  if (stride <= 0) {
+    return NULL;
+  }
+
+  image = (mlib_image *)mlib_malloc(sizeof(mlib_image));
+  if (image == NULL) {
+    return NULL;
+  }
+
+  if (mlib_ImageSet(image, type, channels, width, height, stride, data) == NULL) {
+    mlib_free(image);
+    image = NULL;
+  }
+
+  return image;
+}
+
+/***************************************************************/
+mlib_image *mlib_ImageCreate(mlib_type type,
+                             mlib_s32  channels,
+                             mlib_s32  width,
+                             mlib_s32  height)
+{
+  mlib_image *image;
+  mlib_s32        wb;                /* width in bytes */
+  void       *data;
+
+/* sanity check */
+  if (width <= 0 || height <= 0 || channels < 1 || channels > 4) {
+    return NULL;
+  };
+
+  switch (type) {
+    case MLIB_DOUBLE:
+      wb = width * channels * 8;
+      break;
+    case MLIB_FLOAT:
+    case MLIB_INT:
+      wb = width * channels * 4;
+      break;
+    case MLIB_USHORT:
+    case MLIB_SHORT:
+      wb = width * channels * 2;
+      break;
+    case MLIB_BYTE:
+      wb = width * channels;
+      break;
+    case MLIB_BIT:
+      wb = (width * channels + 7) / 8;
+      break;
+    default:
+      return NULL;
+  }
+
+  data = mlib_malloc(wb * height);
+  if (data == NULL) {
+    return NULL;
+  }
+
+  image = (mlib_image *)mlib_malloc(sizeof(mlib_image));
+  if (image == NULL) {
+    mlib_free(data);
+    return NULL;
+  };
+
+  image -> type     = type;
+  image -> channels = channels;
+  image -> width    = width;
+  image -> height   = height;
+  image -> stride   = wb;
+  image -> data     = data;
+  image -> flags    = ((width & 0xf) << 8);        /* set width field */
+  image -> flags   |= ((height & 0xf) << 12);      /* set height field */
+  image -> flags   |= ((wb & 0xf) << 16);          /* set stride field */
+  image -> flags   |= (mlib_addr)data & 0xff;
+  image -> format   = MLIB_FORMAT_UNKNOWN;
+
+  image -> paddings[0] = 0;
+  image -> paddings[1] = 0;
+  image -> paddings[2] = 0;
+  image -> paddings[3] = 0;
+
+  image -> bitoffset = 0;
+
+  if ((type == MLIB_BIT) && (wb * 8 != width * channels)) {
+    image -> flags |= MLIB_IMAGE_ONEDVECTOR;       /* not 1-d vector */
+  }
+
+  image -> flags &= MLIB_IMAGE_ATTRIBUTESET;
+  image -> state  = NULL;
+
+  return image;
+}
+
+/***************************************************************/
+void mlib_ImageDelete(mlib_image *img)
+{
+  if (img == NULL) return;
+  if ((img -> flags & MLIB_IMAGE_USERALLOCATED) == 0) {
+    mlib_free(img -> data);
+  }
+
+  mlib_ImageDeleteRowTable(img);
+  mlib_free(img);
+}
+
+/***************************************************************/
+mlib_image *mlib_ImageCreateSubimage(mlib_image *img,
+                                     mlib_s32   x,
+                                     mlib_s32   y,
+                                     mlib_s32   w,
+                                     mlib_s32   h)
+{
+  mlib_image     *subimage;
+  mlib_type      type;
+  mlib_s32       channels;
+  mlib_s32       width;                 /* for parent image */
+  mlib_s32       height;                /* for parent image */
+  mlib_s32       stride;
+  mlib_s32       bitoffset;
+  void           *data;
+
+/* sanity check */
+  if (w <= 0 || h <= 0 || img == NULL) return NULL;
+
+  type     = img -> type;
+  channels = img -> channels;
+  width    = img -> width;
+  height   = img -> height;
+  stride   = img -> stride;
+
+/* clip the sub-image with respect to the parent image */
+  if (((x + w) <= 0) || ((y + h) <= 0) ||
+      (x >= width) || (y >= height)) {
+    return NULL;
+  }
+  else {
+    if (x < 0) {
+      w += x;                                        /* x is negative */
+      x = 0;
+    }
+
+    if (y < 0) {
+      h += y;                                        /* y is negative */
+      y = 0;
+    }
+
+    if ((x + w) > width) {
+      w = width - x;
+    }
+
+    if ((y + h) > height) {
+      h = height - y;
+    }
+  }
+
+/* compute sub-image origin */
+  data = (mlib_u8 *)(img -> data) + y * stride;
+
+  switch (type) {
+    case MLIB_DOUBLE:
+      data = (mlib_u8 *)data + x * channels * 8;
+      break;
+    case MLIB_FLOAT:
+    case MLIB_INT:
+      data = (mlib_u8 *)data + x * channels * 4;
+      break;
+    case MLIB_USHORT:
+    case MLIB_SHORT:
+      data = (mlib_u8 *)data + x * channels * 2;
+      break;
+    case MLIB_BYTE:
+      data = (mlib_u8 *)data + x * channels;
+      break;
+    case MLIB_BIT:
+      bitoffset = img -> bitoffset;
+      data = (mlib_u8 *)data + (x * channels + bitoffset) / 8;
+      bitoffset = (x * channels + bitoffset) & 7;
+      break;
+    default:
+      return NULL;
+  }
+
+  subimage = mlib_ImageCreateStruct(type,
+                                    channels,
+                                    w,
+                                    h,
+                                    stride,
+                                    data);
+
+  if (subimage != NULL && type == MLIB_BIT)
+    subimage -> bitoffset = bitoffset;
+
+  return subimage;
+}
+
+/***************************************************************/
+mlib_image *mlib_ImageSetSubimage(mlib_image       *dst,
+                                  const mlib_image *src,
+                                  mlib_s32         x,
+                                  mlib_s32         y,
+                                  mlib_s32         w,
+                                  mlib_s32         h)
+{
+  mlib_type  type     = src -> type;
+  mlib_s32   channels = src -> channels;
+  mlib_s32   stride   = src -> stride;
+  mlib_u8    *data    = src -> data;
+  mlib_s32   bitoffset;
+
+  data += y * stride;
+
+  switch (type) {
+    case MLIB_DOUBLE:
+      data += channels * x * 8;
+      break;
+    case MLIB_FLOAT:
+    case MLIB_INT:
+      data += channels * x * 4;
+      break;
+    case MLIB_USHORT:
+    case MLIB_SHORT:
+      data += channels * x * 2;
+      break;
+    case MLIB_BYTE:
+      data += channels * x;
+      break;
+    case MLIB_BIT:
+      bitoffset = src -> bitoffset + channels * x;
+      data += (bitoffset >= 0) ? bitoffset/8 : (bitoffset - 7)/8; /* with rounding toward -Inf */
+      bitoffset &= 7;
+      break;
+    default:
+      return NULL;
+  }
+
+  if (h > 0) {
+    dst = mlib_ImageSet(dst, type, channels, w, h, stride, data);
+  } else {
+    h = - h;
+    dst = mlib_ImageSet(dst, type, channels, w, h, - stride, data + (h - 1)*stride);
+  }
+
+  if (dst != NULL && type == MLIB_BIT) {
+    dst -> bitoffset = bitoffset;
+  }
+
+  return dst;
+}
+
+/***************************************************************/
+void *mlib_ImageCreateRowTable(mlib_image *img)
+{
+  mlib_u8  **rtable, *tline;
+  mlib_s32 i, im_height, im_stride;
+
+  if (img == NULL) return NULL;
+  if (img -> state)  return img -> state;
+
+  im_height = mlib_ImageGetHeight(img);
+  im_stride = mlib_ImageGetStride(img);
+  tline     = mlib_ImageGetData(img);
+  rtable    = mlib_malloc((3 + im_height)*sizeof(mlib_u8 *));
+
+  if (rtable == NULL || tline == NULL) return NULL;
+
+  rtable[0] = 0;
+  rtable[1] = (mlib_u8*)((void **)rtable + 1);
+  rtable[2 + im_height] = (mlib_u8*)((void **)rtable + 1);
+  for (i = 0; i < im_height; i++) {
+    rtable[i+2] = tline;
+    tline    += im_stride;
+  }
+
+  img -> state = ((void **)rtable + 2);
+  return img -> state;
+}
+
+/***************************************************************/
+void mlib_ImageDeleteRowTable(mlib_image *img)
+{
+  void **state;
+
+  if (img == NULL) return;
+
+  state = img -> state;
+  if (!state) return;
+
+  mlib_free(state - 2);
+  img -> state = 0;
+}
+
+/***************************************************************/
+mlib_status mlib_ImageSetPaddings(mlib_image *img,
+                                  mlib_u8    left,
+                                  mlib_u8    top,
+                                  mlib_u8    right,
+                                  mlib_u8    bottom)
+{
+  if (img == NULL) return MLIB_FAILURE;
+
+  if ((left + right) >= img -> width ||
+      (top + bottom) >= img -> height) return MLIB_OUTOFRANGE;
+
+  img -> paddings[0] = left;
+  img -> paddings[1] = top;
+  img -> paddings[2] = right;
+  img -> paddings[3] = bottom;
+
+  return MLIB_SUCCESS;
+}
+
+/***************************************************************/
+mlib_status mlib_ImageSetFormat(mlib_image  *img,
+                                mlib_format format)
+{
+  if (img == NULL) return MLIB_FAILURE;
+
+  img -> format = format;
+
+  return MLIB_SUCCESS;
+}
+
+/***************************************************************/