1/*
2 * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27/*
28 * FUNCTIONS
29 *      mlib_ImageConvClearEdge  - Set edge of an image to a specific color.
30 *
31 * SYNOPSIS
32 *      mlib_status mlib_ImageConvClearEdge(mlib_image     *dst,
33 *                                          mlib_s32       dx_l,
34 *                                          mlib_s32       dx_r,
35 *                                          mlib_s32       dy_t,
36 *                                          mlib_s32       dy_b,
37 *                                          const mlib_s32 *color,
38 *                                          mlib_s32       cmask)
39 *
40 * ARGUMENT
41 *      dst       Pointer to an image.
42 *      dx_l      Number of columns on the left side of the
43 *                image to be cleared.
44 *      dx_r      Number of columns on the right side of the
45 *                image to be cleared.
46 *      dy_t      Number of rows on the top edge of the
47 *                image to be cleared.
48 *      dy_b      Number of rows on the top edge of the
49 *                image to be cleared.
50 *      color     Pointer to the color that the edges are set to.
51 *      cmask     Channel mask to indicate the channels to be convolved.
52 *                Each bit of which represents a channel in the image. The
53 *                channels corresponded to 1 bits are those to be processed.
54 *
55 * RESTRICTION
56 *      dst can have 1, 2, 3 or 4 channels of MLIB_BYTE or MLIB_SHORT or MLIB_INT
57 *      data type.
58 *
59 * DESCRIPTION
60 *      Set edge of an image to a specific color. (VIS version)
61 *      The unselected channels are not overwritten.
62 *      If src and dst have just one channel,
63 *      cmask is ignored.
64 */
65
66#include "mlib_image.h"
67#include "mlib_ImageConvEdge.h"
68
69/***************************************************************/
70#define EDGES(chan, type, mask)                                       \
71  {                                                                   \
72    type *pdst = (type *) mlib_ImageGetData(dst);                     \
73    type color_i;                                                     \
74    mlib_s32 dst_stride = mlib_ImageGetStride(dst) / sizeof(type);    \
75    mlib_s32 i, j, l;                                                 \
76    mlib_s32 testchan;                                                \
77                                                                      \
78    testchan = 1;                                                     \
79    for (l = chan - 1; l >= 0; l--) {                                 \
80      if ((mask & testchan) == 0) {                                   \
81        testchan <<= 1;                                               \
82        continue;                                                     \
83      }                                                               \
84      testchan <<= 1;                                                 \
85      color_i = (type)color[l];                                       \
86      for (j = 0; j < dx_l; j++) {                                    \
87        for (i = dy_t; i < (dst_height - dy_b); i++) {                \
88          pdst[i*dst_stride + l + j*chan] = color_i;                  \
89        }                                                             \
90      }                                                               \
91      for (j = 0; j < dx_r; j++) {                                    \
92        for (i = dy_t; i < (dst_height - dy_b); i++) {                \
93          pdst[i*dst_stride + l+(dst_width-1 - j)*chan] = color_i;    \
94        }                                                             \
95      }                                                               \
96      for (i = 0; i < dy_t; i++) {                                    \
97        for (j = 0; j < dst_width; j++) {                             \
98          pdst[i*dst_stride + l + j*chan] = color_i;                  \
99        }                                                             \
100      }                                                               \
101      for (i = 0; i < dy_b; i++) {                                    \
102        for (j = 0; j < dst_width; j++) {                             \
103          pdst[(dst_height-1 - i)*dst_stride + l + j*chan] = color_i; \
104        }                                                             \
105      }                                                               \
106    }                                                                 \
107  }
108
109/***************************************************************/
110mlib_status mlib_ImageConvClearEdge(mlib_image     *dst,
111                                    mlib_s32       dx_l,
112                                    mlib_s32       dx_r,
113                                    mlib_s32       dy_t,
114                                    mlib_s32       dy_b,
115                                    const mlib_s32 *color,
116                                    mlib_s32       cmask)
117{
118  mlib_s32 dst_width = mlib_ImageGetWidth(dst);
119  mlib_s32 dst_height = mlib_ImageGetHeight(dst);
120  mlib_s32 channel = mlib_ImageGetChannels(dst);
121
122  if (dx_l + dx_r > dst_width) {
123    dx_l = dst_width;
124    dx_r = 0;
125  }
126
127  if (dy_t + dy_b > dst_height) {
128    dy_t = dst_height;
129    dy_b = 0;
130  }
131
132  if (channel == 1)
133    cmask = 1;
134
135  switch (mlib_ImageGetType(dst)) {
136    case MLIB_BIT:
137      return mlib_ImageConvClearEdge_Bit(dst, dx_l, dx_r, dy_t, dy_b, color, cmask);
138    case MLIB_BYTE:
139      EDGES(channel, mlib_u8, cmask)
140        break;
141    case MLIB_SHORT:
142    case MLIB_USHORT:
143      EDGES(channel, mlib_s16, cmask)
144        break;
145    case MLIB_INT:
146      EDGES(channel, mlib_s32, cmask)
147        break;
148    default:
149      return MLIB_FAILURE;
150  }
151
152  return MLIB_SUCCESS;
153}
154
155/***************************************************************/
156mlib_status mlib_ImageConvZeroEdge(mlib_image *dst,
157                                   mlib_s32   dx_l,
158                                   mlib_s32   dx_r,
159                                   mlib_s32   dy_t,
160                                   mlib_s32   dy_b,
161                                   mlib_s32   cmask)
162{
163  mlib_d64 zero[4] = { 0, 0, 0, 0 };
164  mlib_type type = mlib_ImageGetType(dst);
165
166  if (type == MLIB_FLOAT || type == MLIB_DOUBLE) {
167    return mlib_ImageConvClearEdge_Fp(dst, dx_l, dx_r, dy_t, dy_b, zero, cmask);
168  }
169  else {
170    return mlib_ImageConvClearEdge(dst, dx_l, dx_r, dy_t, dy_b, (mlib_s32 *) zero, cmask);
171  }
172}
173
174/***************************************************************/
175