Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
38918 views
/*1* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/242526/*27* FUNCTION28* mlib_ImageCreateStruct - create image data structure29* mlib_ImageCreate - create image data structure and allocate30* memory for image data31* mlib_ImageDelete - delete image32* mlib_ImageCreateSubimage - create sub-image33*34* mlib_ImageCreateRowTable - create row starts pointer table35* mlib_ImageDeleteRowTable - delete row starts pointer table36*37* mlib_ImageSetPaddings - set paddings for clipping box borders38*39* mlib_ImageSetFormat - set image format40*41* SYNOPSIS42* mlib_image *mlib_ImageCreateStruct(mlib_type type,43* mlib_s32 channels,44* mlib_s32 width,45* mlib_s32 height,46* mlib_s32 stride,47* const void *data)48*49* mlib_image *mlib_ImageCreate(mlib_type type,50* mlib_s32 channels,51* mlib_s32 width,52* mlib_s32 height)53*54* void mlib_ImageDelete(mlib_image *img)55*56* mlib_image *mlib_ImageCreateSubimage(mlib_image *img,57* mlib_s32 x,58* mlib_s32 y,59* mlib_s32 w,60* mlib_s32 h)61*62* void *mlib_ImageCreateRowTable(mlib_image *img)63*64* void mlib_ImageDeleteRowTable(mlib_image *img)65*66* mlib_status mlib_ImageSetPaddings(mlib_image *img,67* mlib_u8 left,68* mlib_u8 top,69* mlib_u8 right,70* mlib_u8 bottom)71*72* mlib_status mlib_ImageSetFormat(mlib_image *img,73* mlib_format format)74* ARGUMENTS75* img pointer to image data structure76* type image data type, one of MLIB_BIT, MLIB_BYTE, MLIB_SHORT,77* MLIB_USHORT, MLIB_INT, MLIB_FLOAT or MLIB_DOUBLE78* channels number of image channels79* width image width in pixels80* height image height in pixels81* stride linebytes( bytes to next row) of the image82* data pointer to image data allocated by user83* x x coordinate of the left border in the source image84* y y coordinate of the top border in the source image85* w width of the sub-image86* h height of the sub-image87* left clipping box left padding88* top clipping box top padding89* right clipping box right padding90* bottom clipping box bottom padding91* format image format92*93* DESCRIPTION94* mlib_ImageCreateStruct() creates a mediaLib image data structure95* using parameter supplied by user.96*97* mlib_ImageCreate() creates a mediaLib image data structure and98* allocates memory space for image data.99*100* mlib_ImageDelete() deletes the mediaLib image data structure101* and frees the memory space of the image data if it is allocated102* through mlib_ImageCreate().103*104* mlib_ImageCreateSubimage() creates a mediaLib image structure105* for a sub-image based on a source image.106*107* mlib_ImageCreateRowTable() creates row starts pointer table and108* puts it into mlib_image->state field.109*110* mlib_ImageDeleteRowTable() deletes row starts pointer table from111* image and puts NULL into mlib_image->state field.112*113* mlib_ImageSetPaddings() sets new values for the clipping box paddings114*115* mlib_ImageSetFormat() sets new value for the image format116*/117118#include <stdlib.h>119#include "mlib_image.h"120#include "mlib_ImageRowTable.h"121#include "mlib_ImageCreate.h"122#include "safe_math.h"123124/***************************************************************/125mlib_image* mlib_ImageSet(mlib_image *image,126mlib_type type,127mlib_s32 channels,128mlib_s32 width,129mlib_s32 height,130mlib_s32 stride,131const void *data)132{133mlib_s32 wb; /* width in bytes */134mlib_s32 mask; /* mask for check of stride */135136if (image == NULL) return NULL;137138/* for some ugly functions calling with incorrect parameters */139image -> type = type;140image -> channels = channels;141image -> width = width;142image -> height = height;143image -> stride = stride;144image -> data = (void *)data;145image -> state = NULL;146image -> format = MLIB_FORMAT_UNKNOWN;147148image -> paddings[0] = 0;149image -> paddings[1] = 0;150image -> paddings[2] = 0;151image -> paddings[3] = 0;152153image -> bitoffset = 0;154155if (width <= 0 || height <= 0 || channels < 1 || channels > 4) {156return NULL;157}158159/* Check if stride == width160* If it is then image can be treated as a 1-D vector161*/162163if (!SAFE_TO_MULT(width, channels)) {164return NULL;165}166167wb = width * channels;168169switch (type) {170case MLIB_DOUBLE:171if (!SAFE_TO_MULT(wb, 8)) {172return NULL;173}174wb *= 8;175mask = 7;176break;177case MLIB_FLOAT:178case MLIB_INT:179if (!SAFE_TO_MULT(wb, 4)) {180return NULL;181}182wb *= 4;183mask = 3;184break;185case MLIB_USHORT:186case MLIB_SHORT:187if (!SAFE_TO_MULT(wb, 2)) {188return NULL;189}190wb *= 2;191mask = 1;192break;193case MLIB_BYTE:194// wb is ready195mask = 0;196break;197case MLIB_BIT:198if (!SAFE_TO_ADD(7, wb)) {199return NULL;200}201wb = (wb + 7) / 8;202mask = 0;203break;204default:205return NULL;206}207208if (stride & mask) {209return NULL;210}211212image -> flags = ((width & 0xf) << 8); /* set width field */213image -> flags |= ((stride & 0xf) << 16); /* set stride field */214image -> flags |= ((height & 0xf) << 12); /* set height field */215image -> flags |= (mlib_addr)data & 0xff;216image -> flags |= MLIB_IMAGE_USERALLOCATED; /* user allocated data */217218if ((stride != wb) ||219((type == MLIB_BIT) && (stride * 8 != width * channels))) {220image -> flags |= MLIB_IMAGE_ONEDVECTOR;221}222223image -> flags &= MLIB_IMAGE_ATTRIBUTESET;224225return image;226}227228/***************************************************************/229mlib_image *mlib_ImageCreateStruct(mlib_type type,230mlib_s32 channels,231mlib_s32 width,232mlib_s32 height,233mlib_s32 stride,234const void *data)235{236mlib_image *image;237if (stride <= 0) {238return NULL;239}240241image = (mlib_image *)mlib_malloc(sizeof(mlib_image));242if (image == NULL) {243return NULL;244}245246if (mlib_ImageSet(image, type, channels, width, height, stride, data) == NULL) {247mlib_free(image);248image = NULL;249}250251return image;252}253254/***************************************************************/255mlib_image *mlib_ImageCreate(mlib_type type,256mlib_s32 channels,257mlib_s32 width,258mlib_s32 height)259{260mlib_image *image;261mlib_s32 wb; /* width in bytes */262void *data;263264/* sanity check */265if (width <= 0 || height <= 0 || channels < 1 || channels > 4) {266return NULL;267};268269if (!SAFE_TO_MULT(width, channels)) {270return NULL;271}272273wb = width * channels;274275switch (type) {276case MLIB_DOUBLE:277if (!SAFE_TO_MULT(wb, 8)) {278return NULL;279}280wb *= 8;281break;282case MLIB_FLOAT:283case MLIB_INT:284if (!SAFE_TO_MULT(wb, 4)) {285return NULL;286}287wb *= 4;288break;289case MLIB_USHORT:290case MLIB_SHORT:291if (!SAFE_TO_MULT(wb, 2)) {292return NULL;293}294wb *= 2;295break;296case MLIB_BYTE:297// wb is ready298break;299case MLIB_BIT:300if (!SAFE_TO_ADD(7, wb)) {301return NULL;302}303wb = (wb + 7) / 8;304break;305default:306return NULL;307}308309if (!SAFE_TO_MULT(wb, height)) {310return NULL;311}312313data = mlib_malloc(wb * height);314if (data == NULL) {315return NULL;316}317318image = (mlib_image *)mlib_malloc(sizeof(mlib_image));319if (image == NULL) {320mlib_free(data);321return NULL;322};323324image -> type = type;325image -> channels = channels;326image -> width = width;327image -> height = height;328image -> stride = wb;329image -> data = data;330image -> flags = ((width & 0xf) << 8); /* set width field */331image -> flags |= ((height & 0xf) << 12); /* set height field */332image -> flags |= ((wb & 0xf) << 16); /* set stride field */333image -> flags |= (mlib_addr)data & 0xff;334image -> format = MLIB_FORMAT_UNKNOWN;335336image -> paddings[0] = 0;337image -> paddings[1] = 0;338image -> paddings[2] = 0;339image -> paddings[3] = 0;340341image -> bitoffset = 0;342343if ((type == MLIB_BIT) && (wb * 8 != width * channels)) {344image -> flags |= MLIB_IMAGE_ONEDVECTOR; /* not 1-d vector */345}346347image -> flags &= MLIB_IMAGE_ATTRIBUTESET;348image -> state = NULL;349350return image;351}352353/***************************************************************/354void mlib_ImageDelete(mlib_image *img)355{356if (img == NULL) return;357if ((img -> flags & MLIB_IMAGE_USERALLOCATED) == 0) {358mlib_free(img -> data);359}360361mlib_ImageDeleteRowTable(img);362mlib_free(img);363}364365/***************************************************************/366mlib_image *mlib_ImageCreateSubimage(mlib_image *img,367mlib_s32 x,368mlib_s32 y,369mlib_s32 w,370mlib_s32 h)371{372mlib_image *subimage;373mlib_type type;374mlib_s32 channels;375mlib_s32 width; /* for parent image */376mlib_s32 height; /* for parent image */377mlib_s32 stride;378mlib_s32 bitoffset = 0;379void *data;380381/* sanity check */382if (w <= 0 || h <= 0 || img == NULL) return NULL;383384type = img -> type;385channels = img -> channels;386width = img -> width;387height = img -> height;388stride = img -> stride;389390/* clip the sub-image with respect to the parent image */391if (((x + w) <= 0) || ((y + h) <= 0) ||392(x >= width) || (y >= height)) {393return NULL;394}395else {396if (x < 0) {397w += x; /* x is negative */398x = 0;399}400401if (y < 0) {402h += y; /* y is negative */403y = 0;404}405406if ((x + w) > width) {407w = width - x;408}409410if ((y + h) > height) {411h = height - y;412}413}414415/* compute sub-image origin */416data = (mlib_u8 *)(img -> data) + y * stride;417418switch (type) {419case MLIB_DOUBLE:420data = (mlib_u8 *)data + x * channels * 8;421break;422case MLIB_FLOAT:423case MLIB_INT:424data = (mlib_u8 *)data + x * channels * 4;425break;426case MLIB_USHORT:427case MLIB_SHORT:428data = (mlib_u8 *)data + x * channels * 2;429break;430case MLIB_BYTE:431data = (mlib_u8 *)data + x * channels;432break;433case MLIB_BIT:434bitoffset = img -> bitoffset;435data = (mlib_u8 *)data + (x * channels + bitoffset) / 8;436bitoffset = (x * channels + bitoffset) & 7;437break;438default:439return NULL;440}441442subimage = mlib_ImageCreateStruct(type,443channels,444w,445h,446stride,447data);448449if (subimage != NULL && type == MLIB_BIT)450subimage -> bitoffset = bitoffset;451452return subimage;453}454455/***************************************************************/456mlib_image *mlib_ImageSetSubimage(mlib_image *dst,457const mlib_image *src,458mlib_s32 x,459mlib_s32 y,460mlib_s32 w,461mlib_s32 h)462{463mlib_type type = src -> type;464mlib_s32 channels = src -> channels;465mlib_s32 stride = src -> stride;466mlib_u8 *data = src -> data;467mlib_s32 bitoffset = 0;468469data += y * stride;470471switch (type) {472case MLIB_DOUBLE:473data += channels * x * 8;474break;475case MLIB_FLOAT:476case MLIB_INT:477data += channels * x * 4;478break;479case MLIB_USHORT:480case MLIB_SHORT:481data += channels * x * 2;482break;483case MLIB_BYTE:484data += channels * x;485break;486case MLIB_BIT:487bitoffset = src -> bitoffset + channels * x;488data += (bitoffset >= 0) ? bitoffset/8 : (bitoffset - 7)/8; /* with rounding toward -Inf */489bitoffset &= 7;490break;491default:492return NULL;493}494495if (h > 0) {496dst = mlib_ImageSet(dst, type, channels, w, h, stride, data);497} else {498h = - h;499dst = mlib_ImageSet(dst, type, channels, w, h, - stride, data + (h - 1)*stride);500}501502if (dst != NULL && type == MLIB_BIT) {503dst -> bitoffset = bitoffset;504}505506return dst;507}508509/***************************************************************/510void *mlib_ImageCreateRowTable(mlib_image *img)511{512mlib_u8 **rtable, *tline;513mlib_s32 i, im_height, im_stride;514515if (img == NULL) return NULL;516if (img -> state) return img -> state;517518im_height = mlib_ImageGetHeight(img);519im_stride = mlib_ImageGetStride(img);520tline = mlib_ImageGetData(img);521if (tline == NULL) return NULL;522rtable = mlib_malloc((3 + im_height)*sizeof(mlib_u8 *));523if (rtable == NULL) return NULL;524525rtable[0] = 0;526rtable[1] = (mlib_u8*)((void **)rtable + 1);527rtable[2 + im_height] = (mlib_u8*)((void **)rtable + 1);528for (i = 0; i < im_height; i++) {529rtable[i+2] = tline;530tline += im_stride;531}532533img -> state = ((void **)rtable + 2);534return img -> state;535}536537/***************************************************************/538void mlib_ImageDeleteRowTable(mlib_image *img)539{540void **state;541542if (img == NULL) return;543544state = img -> state;545if (!state) return;546547mlib_free(state - 2);548img -> state = 0;549}550551/***************************************************************/552mlib_status mlib_ImageSetPaddings(mlib_image *img,553mlib_u8 left,554mlib_u8 top,555mlib_u8 right,556mlib_u8 bottom)557{558if (img == NULL) return MLIB_FAILURE;559560if ((left + right) >= img -> width ||561(top + bottom) >= img -> height) return MLIB_OUTOFRANGE;562563img -> paddings[0] = left;564img -> paddings[1] = top;565img -> paddings[2] = right;566img -> paddings[3] = bottom;567568return MLIB_SUCCESS;569}570571/***************************************************************/572mlib_status mlib_ImageSetFormat(mlib_image *img,573mlib_format format)574{575if (img == NULL) return MLIB_FAILURE;576577img -> format = format;578579return MLIB_SUCCESS;580}581582/***************************************************************/583584585