jdk/src/share/native/sun/java2d/loops/TransformHelper.c
author flar
Mon, 06 Dec 2010 21:45:48 -0800
changeset 7487 9b031d062ede
parent 5506 202f599c92aa
child 9830 692619a439fc
permissions -rw-r--r--
6775317: Improve performance of non-AA transformed rectangles and single wide lines in software pipelines Reviewed-by: jgodinez, prr
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#include <stdlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#include "jni_util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
#include "math.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
#include "GraphicsPrimitiveMgr.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include "Region.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
#include "sun_java2d_loops_TransformHelper.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#include "java_awt_image_AffineTransformOp.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * The stub functions replace the bilinear and bicubic interpolation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * functions with NOP versions so that the performance of the helper
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * functions that fetch the data can be more directly tested.  They
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * are not compiled or enabled by default.  Change the following
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * #undef to a #define to build the stub functions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * When compiled, they are enabled by the environment variable TXSTUB.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * When compiled, there is also code to disable the VIS versions and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * use the C versions in this file in their place by defining the TXNOVIS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * environment variable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
#undef MAKE_STUBS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
/* The number of IntArgbPre samples to store in the temporary buffer. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
#define LINE_SIZE       2048
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
/* The size of a stack allocated buffer to hold edge coordinates (see below). */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
#define MAXEDGES 1024
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
/* Declare the software interpolation functions. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
static TransformInterpFunc BilinearInterp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
static TransformInterpFunc BicubicInterp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
#ifdef MAKE_STUBS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
/* Optionally Declare the stub interpolation functions. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
static TransformInterpFunc BilinearInterpStub;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
static TransformInterpFunc BicubicInterpStub;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
#endif /* MAKE_STUBS */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * Initially choose the software interpolation functions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * These choices can be overridden by platform code that runs during the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * primitive registration phase of initialization by storing pointers to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * better functions in these pointers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * Compiling the stubs also turns on code below that can re-install the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * software functions or stub functions on the first call to this primitive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
TransformInterpFunc *pBilinearFunc = BilinearInterp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
TransformInterpFunc *pBicubicFunc = BicubicInterp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * Fill the edge buffer with pairs of coordinates representing the maximum
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * left and right pixels of the destination surface that should be processed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * on each scanline, clipped to the bounds parameter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * The number of scanlines to calculate is implied by the bounds parameter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * Only pixels that map back through the specified (inverse) transform to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * source coordinate that falls within the (0, 0, sw, sh) bounds of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * source image should be processed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * pEdgeBuf points to an array of jints that holds MAXEDGES*2 values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * If more storage is needed, then this function allocates a new buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * In either case, a pointer to the buffer actually used to store the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * results is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * The caller is responsible for freeing the buffer if the return value
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 * is not the same as the original pEdgeBuf passed in.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
static jint *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
calculateEdges(jint *pEdgeBuf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
               SurfaceDataBounds *pBounds,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
               TransformInfo *pItxInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
               jlong xbase, jlong ybase,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
               juint sw, juint sh)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    jint *pEdges;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    jlong dxdxlong, dydxlong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    jlong dxdylong, dydylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    jlong drowxlong, drowylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    jint dx1, dy1, dx2, dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    dxdxlong = DblToLong(pItxInfo->dxdx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    dydxlong = DblToLong(pItxInfo->dydx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    dxdylong = DblToLong(pItxInfo->dxdy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    dydylong = DblToLong(pItxInfo->dydy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    dx1 = pBounds->x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    dy1 = pBounds->y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    dx2 = pBounds->x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    dy2 = pBounds->y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    if ((dy2-dy1) > MAXEDGES) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        pEdgeBuf = malloc(2 * (dy2-dy1) * sizeof (*pEdges));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    pEdges = pEdgeBuf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    drowxlong = (dx2-dx1-1) * dxdxlong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    drowylong = (dx2-dx1-1) * dydxlong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    while (dy1 < dy2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        jlong xlong, ylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        dx1 = pBounds->x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        dx2 = pBounds->x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        xlong = xbase;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        ylong = ybase;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        while (dx1 < dx2 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
               (((juint) WholeOfLong(ylong)) >= sh ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
                ((juint) WholeOfLong(xlong)) >= sw))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            dx1++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            xlong += dxdxlong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
            ylong += dydxlong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        xlong = xbase + drowxlong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        ylong = ybase + drowylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        while (dx2 > dx1 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
               (((juint) WholeOfLong(ylong)) >= sh ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                ((juint) WholeOfLong(xlong)) >= sw))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            dx2--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            xlong -= dxdxlong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            ylong -= dydxlong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        *pEdges++ = dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        *pEdges++ = dx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        /* Increment to next scanline */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        xbase += dxdylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        ybase += dydylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        dy1++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    return pEdgeBuf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
 * Class:     sun_java2d_loops_TransformHelper
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
 * Method:    Transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
 * Signature: (Lsun/java2d/loops/MaskBlit;Lsun/java2d/SurfaceData;Lsun/java2d/SurfaceData;Ljava/awt/Composite;Lsun/java2d/pipe/Region;Ljava/awt/geom/AffineTransform;IIIIIIIII[I)V
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
JNIEXPORT void JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
Java_sun_java2d_loops_TransformHelper_Transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    (JNIEnv *env, jobject self,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     jobject maskblit,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     jobject srcData, jobject dstData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     jobject comp, jobject clip,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     jobject itxform, jint txtype,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     jint sx1, jint sy1, jint sx2, jint sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     jint dx1, jint dy1, jint dx2, jint dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     jintArray edgeArray, jint dxoff, jint dyoff)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    SurfaceDataOps *srcOps;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    SurfaceDataOps *dstOps;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    SurfaceDataRasInfo srcInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    SurfaceDataRasInfo dstInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    NativePrimitive *pHelperPrim;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    NativePrimitive *pMaskBlitPrim;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    CompositeInfo compInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    RegionData clipInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    TransformInfo itxInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    jint maxlinepix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    TransformHelperFunc *pHelperFunc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    TransformInterpFunc *pInterpFunc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    jint edgebuf[MAXEDGES * 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    jint *pEdges;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    jdouble x, y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    jlong xbase, ybase;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    jlong dxdxlong, dydxlong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    jlong dxdylong, dydylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
#ifdef MAKE_STUBS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    static int th_initialized;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    /* For debugging only - used to swap in alternate funcs for perf testing */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    if (!th_initialized) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        if (getenv("TXSTUB") != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            pBilinearFunc = BilinearInterpStub;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            pBicubicFunc = BicubicInterpStub;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        } else if (getenv("TXNOVIS") != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            pBilinearFunc = BilinearInterp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            pBicubicFunc = BicubicInterp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        th_initialized = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
#endif /* MAKE_STUBS */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    pHelperPrim = GetNativePrim(env, self);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    if (pHelperPrim == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        /* Should never happen... */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    pMaskBlitPrim = GetNativePrim(env, maskblit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    if (pMaskBlitPrim == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        /* Exception was thrown by GetNativePrim */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    if (pMaskBlitPrim->pCompType->getCompInfo != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        (*pMaskBlitPrim->pCompType->getCompInfo)(env, &compInfo, comp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    if (Region_GetInfo(env, clip, &clipInfo)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    srcOps = SurfaceData_GetOps(env, srcData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    dstOps = SurfaceData_GetOps(env, dstData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    if (srcOps == 0 || dstOps == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * Grab the appropriate pointer to the helper and interpolation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * routines and calculate the maximum number of destination pixels
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * that can be processed in one intermediate buffer based on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * size of the buffer and the number of samples needed per pixel.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    switch (txtype) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    case java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        pHelperFunc = pHelperPrim->funcs.transformhelpers->nnHelper;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        pInterpFunc = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        maxlinepix = LINE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        pHelperFunc = pHelperPrim->funcs.transformhelpers->blHelper;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        pInterpFunc = pBilinearFunc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        maxlinepix = LINE_SIZE / 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    case java_awt_image_AffineTransformOp_TYPE_BICUBIC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        pHelperFunc = pHelperPrim->funcs.transformhelpers->bcHelper;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        pInterpFunc = pBicubicFunc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        maxlinepix = LINE_SIZE / 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    srcInfo.bounds.x1 = sx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    srcInfo.bounds.y1 = sy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    srcInfo.bounds.x2 = sx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    srcInfo.bounds.y2 = sy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    dstInfo.bounds.x1 = dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    dstInfo.bounds.y1 = dy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    dstInfo.bounds.x2 = dx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    dstInfo.bounds.y2 = dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    SurfaceData_IntersectBounds(&dstInfo.bounds, &clipInfo.bounds);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    if (srcOps->Lock(env, srcOps, &srcInfo, pHelperPrim->srcflags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        != SD_SUCCESS)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    if (dstOps->Lock(env, dstOps, &dstInfo, pMaskBlitPrim->dstflags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        != SD_SUCCESS)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    Region_IntersectBounds(&clipInfo, &dstInfo.bounds);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    Transform_GetInfo(env, itxform, &itxInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    dxdxlong = DblToLong(itxInfo.dxdx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    dydxlong = DblToLong(itxInfo.dydx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    dxdylong = DblToLong(itxInfo.dxdy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    dydylong = DblToLong(itxInfo.dydy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    x = dxoff+dstInfo.bounds.x1+0.5; /* Center of pixel x1 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    y = dyoff+dstInfo.bounds.y1+0.5; /* Center of pixel y1 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    Transform_transform(&itxInfo, &x, &y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    xbase = DblToLong(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    ybase = DblToLong(y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    pEdges = calculateEdges(edgebuf, &dstInfo.bounds, &itxInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                            xbase, ybase, sx2-sx1, sy2-sy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    if (!Region_IsEmpty(&clipInfo)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        srcOps->GetRasInfo(env, srcOps, &srcInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        dstOps->GetRasInfo(env, dstOps, &dstInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        if (srcInfo.rasBase && dstInfo.rasBase) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            union {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                jlong align;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                jint data[LINE_SIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            } rgb;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            SurfaceDataBounds span;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            Region_StartIteration(env, &clipInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            while (Region_NextIteration(&clipInfo, &span)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                jlong rowxlong, rowylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                void *pDst;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                dy1 = span.y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                dy2 = span.y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                rowxlong = xbase + (dy1 - dstInfo.bounds.y1) * dxdylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                rowylong = ybase + (dy1 - dstInfo.bounds.y1) * dydylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                while (dy1 < dy2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                    jlong xlong, ylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                    /* Note - process at most one scanline at a time. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                    dx1 = pEdges[(dy1 - dstInfo.bounds.y1) * 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                    dx2 = pEdges[(dy1 - dstInfo.bounds.y1) * 2 + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                    if (dx1 < span.x1) dx1 = span.x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                    if (dx2 > span.x2) dx2 = span.x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                    /* All pixels from dx1 to dx2 have centers in bounds */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                    while (dx1 < dx2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                        /* Can process at most one buffer full at a time */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                        jint numpix = dx2 - dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                        if (numpix > maxlinepix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                            numpix = maxlinepix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                        xlong =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                            rowxlong + ((dx1 - dstInfo.bounds.x1) * dxdxlong);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                        ylong =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                            rowylong + ((dx1 - dstInfo.bounds.x1) * dydxlong);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                        /* Get IntArgbPre pixel data from source */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                        (*pHelperFunc)(&srcInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                                       rgb.data, numpix,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                                       xlong, dxdxlong,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                                       ylong, dydxlong);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                        /* Interpolate result pixels if needed */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                        if (pInterpFunc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                            (*pInterpFunc)(rgb.data, numpix,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                                           FractOfLong(xlong-LongOneHalf),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                                           FractOfLong(dxdxlong),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                                           FractOfLong(ylong-LongOneHalf),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                                           FractOfLong(dydxlong));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                        /* Store/Composite interpolated pixels into dest */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                        pDst = PtrCoord(dstInfo.rasBase,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                                        dx1, dstInfo.pixelStride,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                                        dy1, dstInfo.scanStride);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                        (*pMaskBlitPrim->funcs.maskblit)(pDst, rgb.data,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                                                         0, 0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                                                         numpix, 1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                                                         &dstInfo, &srcInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                                                         pMaskBlitPrim,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                                                         &compInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                        /* Increment to next buffer worth of input pixels */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                        dx1 += maxlinepix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                    /* Increment to next scanline */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                    rowxlong += dxdylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                    rowylong += dydylong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                    dy1++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            Region_EndIteration(env, &clipInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        SurfaceData_InvokeRelease(env, dstOps, &dstInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    if (!JNU_IsNull(env, edgeArray)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        (*env)->SetIntArrayRegion(env, edgeArray, 0, 1, &dstInfo.bounds.y1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        (*env)->SetIntArrayRegion(env, edgeArray, 1, 1, &dstInfo.bounds.y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        (*env)->SetIntArrayRegion(env, edgeArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                                  2, (dstInfo.bounds.y2 - dstInfo.bounds.y1)*2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                                  pEdges);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    if (pEdges != edgebuf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        free(pEdges);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
#define BL_INTERP_V1_to_V2_by_F(v1, v2, f) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    (((v1)<<8) + ((v2)-(v1))*(f))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
#define BL_ACCUM(comp) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    do { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        jint c1 = ((jubyte *) pRGB)[comp]; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        jint c2 = ((jubyte *) pRGB)[comp+4]; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        jint cR = BL_INTERP_V1_to_V2_by_F(c1, c2, xfactor); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        c1 = ((jubyte *) pRGB)[comp+8]; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        c2 = ((jubyte *) pRGB)[comp+12]; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        c2 = BL_INTERP_V1_to_V2_by_F(c1, c2, xfactor); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        cR = BL_INTERP_V1_to_V2_by_F(cR, c2, yfactor); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        ((jubyte *)pRes)[comp] = (jubyte) ((cR + (1<<15)) >> 16); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
BilinearInterp(jint *pRGB, jint numpix,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
               jint xfract, jint dxfract,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
               jint yfract, jint dyfract)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    jint j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    jint *pRes = pRGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    for (j = 0; j < numpix; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        jint xfactor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        jint yfactor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        xfactor = URShift(xfract, 32-8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        yfactor = URShift(yfract, 32-8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        BL_ACCUM(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        BL_ACCUM(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        BL_ACCUM(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        BL_ACCUM(3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        pRes++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        pRGB += 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        xfract += dxfract;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        yfract += dyfract;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
#define SAT(val, max) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    do { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        val &= ~(val >> 31);  /* negatives become 0 */ \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        val -= max;           /* only overflows are now positive */ \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        val &= (val >> 31);   /* positives become 0 */ \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        val += max;           /* range is now [0 -> max] */ \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
#ifdef __sparc
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
/* For sparc, floating point multiplies are faster than integer */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
#define BICUBIC_USE_DBL_LUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
/* For x86, integer multiplies are faster than floating point */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
/* Note that on x86 Linux the choice of best algorithm varies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
 * depending on the compiler optimization and the processor type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
 * Currently, the sun/awt x86 Linux builds are not optimized so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
 * all the variations produce mediocre performance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
 * For now we will use the choice that works best for the Windows
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
 * build until the (lack of) optimization issues on Linux are resolved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
#define BICUBIC_USE_INT_MATH
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
#ifdef BICUBIC_USE_DBL_CAST
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
#define BC_DblToCoeff(v)        (v)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
#define BC_COEFF_ONE            1.0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
#define BC_TYPE                 jdouble
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
#define BC_V_HALF               0.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
#define BC_CompToV(v)           ((jdouble) (v))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
#define BC_STORE_COMPS(pRes) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
    do { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        jint a = (jint) accumA; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        jint r = (jint) accumR; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        jint g = (jint) accumG; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        jint b = (jint) accumB; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        SAT(a, 255); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        SAT(r, a); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        SAT(g, a); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
        SAT(b, a); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        *pRes = ((a << 24) | (r << 16) | (g <<  8) | (b)); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
#endif /* BICUBIC_USE_DBL_CAST */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
#ifdef BICUBIC_USE_DBL_LUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
#define ItoD1(v)    ((jdouble) (v))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
#define ItoD4(v)    ItoD1(v),  ItoD1(v+1),   ItoD1(v+2),   ItoD1(v+3)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
#define ItoD16(v)   ItoD4(v),  ItoD4(v+4),   ItoD4(v+8),   ItoD4(v+12)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
#define ItoD64(v)   ItoD16(v), ItoD16(v+16), ItoD16(v+32), ItoD16(v+48)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
static jdouble ItoD_table[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    ItoD64(0), ItoD64(64), ItoD64(128), ItoD64(192)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
#define BC_DblToCoeff(v)        (v)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
#define BC_COEFF_ONE            1.0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
#define BC_TYPE                 jdouble
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
#define BC_V_HALF               0.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
#define BC_CompToV(v)           ItoD_table[v]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
#define BC_STORE_COMPS(pRes) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    do { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        jint a = (jint) accumA; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        jint r = (jint) accumR; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        jint g = (jint) accumG; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        jint b = (jint) accumB; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        SAT(a, 255); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        SAT(r, a); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        SAT(g, a); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        SAT(b, a); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        *pRes = ((a << 24) | (r << 16) | (g <<  8) | (b)); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
#endif /* BICUBIC_USE_DBL_LUT */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
#ifdef BICUBIC_USE_INT_MATH
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
#define BC_DblToCoeff(v)        ((jint) ((v) * 256))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
#define BC_COEFF_ONE            256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
#define BC_TYPE                 jint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
#define BC_V_HALF               (1 << 15)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
#define BC_CompToV(v)           ((jint) v)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
#define BC_STORE_COMPS(pRes) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
    do { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        accumA >>= 16; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        accumR >>= 16; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        accumG >>= 16; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        accumB >>= 16; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        SAT(accumA, 255); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        SAT(accumR, accumA); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        SAT(accumG, accumA); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        SAT(accumB, accumA); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        *pRes = ((accumA << 24) | (accumR << 16) | (accumG << 8) | (accumB)); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
    } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
#endif /* BICUBIC_USE_INT_MATH */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
#define BC_ACCUM(index, ycindex, xcindex) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    do { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        BC_TYPE factor = bicubic_coeff[xcindex] * bicubic_coeff[ycindex]; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        int rgb; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        rgb = pRGB[index]; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        accumB += BC_CompToV((rgb >>  0) & 0xff) * factor; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        accumG += BC_CompToV((rgb >>  8) & 0xff) * factor; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        accumR += BC_CompToV((rgb >> 16) & 0xff) * factor; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        accumA += BC_CompToV((rgb >> 24) & 0xff) * factor; \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
    } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
static BC_TYPE bicubic_coeff[513];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
static jboolean bicubictableinited;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
init_bicubic_table(jdouble A)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
     * The following formulas are designed to give smooth
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     * results when 'A' is -0.5 or -1.0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    for (i = 0; i < 256; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
        /* r(x) = (A + 2)|x|^3 - (A + 3)|x|^2 + 1 , 0 <= |x| < 1 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        jdouble x = i / 256.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        x = ((A+2)*x - (A+3))*x*x + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        bicubic_coeff[i] = BC_DblToCoeff(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    for (; i < 384; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        /* r(x) = A|x|^3 - 5A|x|^2 + 8A|x| - 4A , 1 <= |x| < 2 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        jdouble x = i / 256.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
        x = ((A*x - 5*A)*x + 8*A)*x - 4*A;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        bicubic_coeff[i] = BC_DblToCoeff(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    bicubic_coeff[384] = (BC_COEFF_ONE - bicubic_coeff[128]*2) / 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    for (i++; i <= 512; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        bicubic_coeff[i] = BC_COEFF_ONE - (bicubic_coeff[512-i] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                                           bicubic_coeff[i-256] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                                           bicubic_coeff[768-i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    bicubictableinited = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
BicubicInterp(jint *pRGB, jint numpix,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
              jint xfract, jint dxfract,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
              jint yfract, jint dyfract)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
    jint i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    jint *pRes = pRGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
    if (!bicubictableinited) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        init_bicubic_table(-0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    for (i = 0; i < numpix; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        BC_TYPE accumA, accumR, accumG, accumB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        jint xfactor, yfactor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        xfactor = URShift(xfract, 32-8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        yfactor = URShift(yfract, 32-8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        accumA = accumR = accumG = accumB = BC_V_HALF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        BC_ACCUM(0, yfactor+256, xfactor+256);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        BC_ACCUM(1, yfactor+256, xfactor+  0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        BC_ACCUM(2, yfactor+256, 256-xfactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        BC_ACCUM(3, yfactor+256, 512-xfactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        BC_ACCUM(4, yfactor+  0, xfactor+256);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        BC_ACCUM(5, yfactor+  0, xfactor+  0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        BC_ACCUM(6, yfactor+  0, 256-xfactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        BC_ACCUM(7, yfactor+  0, 512-xfactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        BC_ACCUM(8, 256-yfactor, xfactor+256);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        BC_ACCUM(9, 256-yfactor, xfactor+  0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        BC_ACCUM(10, 256-yfactor, 256-xfactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        BC_ACCUM(11, 256-yfactor, 512-xfactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        BC_ACCUM(12, 512-yfactor, xfactor+256);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        BC_ACCUM(13, 512-yfactor, xfactor+  0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        BC_ACCUM(14, 512-yfactor, 256-xfactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        BC_ACCUM(15, 512-yfactor, 512-xfactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        BC_STORE_COMPS(pRes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        pRes++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        pRGB += 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        xfract += dxfract;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        yfract += dyfract;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
#ifdef MAKE_STUBS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
BilinearInterpStub(jint *pRGBbase, jint numpix,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                   jint xfract, jint dxfract,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                   jint yfract, jint dyfract)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    jint *pRGB = pRGBbase;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    while (--numpix >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        *pRGBbase = *pRGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        pRGBbase += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        pRGB += 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
BicubicInterpStub(jint *pRGBbase, jint numpix,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                  jint xfract, jint dxfract,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                  jint yfract, jint dyfract)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    jint *pRGB = pRGBbase+5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    while (--numpix >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        *pRGBbase = *pRGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        pRGBbase += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        pRGB += 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
#endif /* MAKE_STUBS */