summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/panorama/Mosaic.java
blob: 80e8263c5412ab6e6d67d3c1c821c1d7cfcef160 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.camera.panorama;

/**
 * The Java interface to JNI calls regarding mosaic stitching.
 *
 * A high-level usage is:
 *
 * Mosaic mosaic = new Mosaic();
 * mosaic.setSourceImageDimensions(width, height);
 * mosaic.reset(blendType);
 *
 * while ((pixels = hasNextImage()) != null) {
 *    mosaic.setSourceImage(pixels);
 * }
 *
 * mosaic.createMosaic(highRes);
 * byte[] result = mosaic.getFinalMosaic();
 *
 */
public class Mosaic {
    /**
     * In this mode, the images are stitched together in the same spatial arrangement as acquired
     * i.e. if the user follows a curvy trajectory, the image boundary of the resulting mosaic will
     * be curved in the same manner. This mode is useful if the user wants to capture a mosaic as
     * if "painting" the scene using the smart-phone device and does not want any corrective warps
     * to distort the captured images.
     */
    public static final int BLENDTYPE_FULL = 0;

    /**
     * This mode is the same as BLENDTYPE_FULL except that the resulting mosaic is rotated
     * to balance the first and last images to be approximately at the same vertical offset in the
     * output mosaic. This is useful when acquiring a mosaic by a typical panning-like motion to
     * remove a one-sided curve in the mosaic (typically due to the camera not staying horizontal
     * during the video capture) and convert it to a more symmetrical "smiley-face" like output.
     */
    public static final int BLENDTYPE_PAN = 1;

    /**
     * This mode compensates for typical "smiley-face" like output in longer mosaics and creates
     * a rectangular mosaic with minimal black borders (by unwrapping the mosaic onto an imaginary
     * cylinder). If the user follows a curved trajectory (instead of a perfect panning trajectory),
     * the resulting mosaic here may suffer from some image distortions in trying to map the
     * trajectory to a cylinder.
     */
    public static final int BLENDTYPE_CYLINDERPAN = 2;

    /**
     * This mode is basically BLENDTYPE_CYLINDERPAN plus doing a rectangle cropping before returning
     * the mosaic. The mode is useful for making the resulting mosaic have a rectangle shape.
     */
    public static final int BLENDTYPE_HORIZONTAL =3;

    static {
        System.loadLibrary("jni_mosaic");
    }

    /**
     * Allocate memory for the image frames at the given resolution.
     *
     * @param width width of the input frames in pixels
     * @param height height of the input frames in pixels
     */
    public native void allocateMosaicMemory(int width, int height);

    /**
     * Free memory allocated by allocateMosaicMemory.
     *
     */
    public native void freeMosaicMemory();

    /**
     * Pass the input image frame to the native layer. Each time the a new
     * source image t is set, the transformation matrix from the first source
     * image to t is computed and returned.
     *
     * @param pixels source image of NV21 format.
     * @return Float array of length 10; first 9 entries correspond to the 3x3
     *         transformation matrix between the first frame and the passed frame,
     *         and the last entry is the number of the passed frame,
     *         where the counting starts from 1.
     */
    public native float[] setSourceImage(byte[] pixels);

    /**
     * This is an alternative to the setSourceImage function above. This should
     * be called when the image data is already on the native side in a fixed
     * byte array. In implementation, this array is filled by the GL thread
     * using glReadPixels directly from GPU memory (where it is accessed by
     * an associated SurfaceTexture).
     *
     * @return Float array of length 10; first 9 entries correspond to the 3x3
     *         transformation matrix between the first frame and the passed frame,
     *         and the last entry is the number of the passed frame,
     *         where the counting starts from 1.
     */
    public native float[] setSourceImageFromGPU();

    /**
     * Set the type of blending.
     *
     * @param type the blending type defined in the class. {BLENDTYPE_FULL,
     *        BLENDTYPE_PAN, BLENDTYPE_CYLINDERPAN, BLENDTYPE_HORIZONTAL}
     */
    public native void setBlendingType(int type);

    /**
     * Tell the native layer to create the final mosaic after all the input frame
     * data have been collected.
     * The case of generating high-resolution mosaic may take dozens of seconds to finish.
     *
     * @param value True means generating a high-resolution mosaic -
     *        which is based on the original images set in setSourceImage().
     *        False means generating a low-resolution version -
     *        which is based on 1/4 downscaled images from the original images.
     */
    public native void createMosaic(boolean value);

    /**
     * Get the data for the created mosaic.
     *
     * @return Returns an integer array which contains the final mosaic in the ARGB_8888 format.
     *         The first MosaicWidth*MosaicHeight values contain the image data, followed by 2
     *         integers corresponding to the values MosaicWidth and MosaicHeight respectively.
     */
    public native int[] getFinalMosaic();

    /**
     * Get the data for the created mosaic.
     *
     * @return Returns a byte array which contains the final mosaic in the NV21 format.
     *         The first MosaicWidth*MosaicHeight*1.5 values contain the image data, followed by
     *         8 bytes which pack the MosaicWidth and MosaicHeight integers into 4 bytes each
     *         respectively.
     */
    public native byte[] getFinalMosaicNV21();

    /**
     * Reset the state of the frame arrays which maintain the captured frame data.
     * Also re-initializes the native mosaic object to make it ready for capturing a new mosaic.
     */
    public native void reset();
}