1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 
41 
42 #include <jni.h>
43 #include <android/log.h>
44 #include <extract.h>
45 #include <alloca.h>
46 #include <stdlib.h>
47 
48 #define LOG_TAG    "extractSyleInfo"
49 #define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
50 
51 // The following part was shamelessly stolen from ResourceTypes.cpp from Android's sources
52 /*
53  * Copyright (C) 2005 The Android Open Source Project
54  *
55  * Licensed under the Apache License, Version 2.0 (the "License");
56  * you may not use this file except in compliance with the License.
57  * You may obtain a copy of the License at
58  *
59  *      http://www.apache.org/licenses/LICENSE-2.0
60  *
61  * Unless required by applicable law or agreed to in writing, software
62  * distributed under the License is distributed on an "AS IS" BASIS,
63  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64  * See the License for the specific language governing permissions and
65  * limitations under the License.
66  */
67 
deserializeInternal(const void * inData,Res_png_9patch * outData)68 static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
69     char* patch = (char*) inData;
70     if (inData != outData) {
71         memmove(&outData->wasDeserialized, patch, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
72         memmove(&outData->paddingLeft, patch + 12, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
73     }
74     outData->wasDeserialized = true;
75     char* data = (char*)outData;
76     data +=  sizeof(Res_png_9patch);
77     outData->xDivs = (int32_t*) data;
78     data +=  outData->numXDivs * sizeof(int32_t);
79     outData->yDivs = (int32_t*) data;
80     data +=  outData->numYDivs * sizeof(int32_t);
81     outData->colors = (uint32_t*) data;
82 }
83 
deserialize(const void * inData)84 Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
85 {
86     if (sizeof(void*) != sizeof(int32_t)) {
87         LOGE("Cannot deserialize on non 32-bit system\n");
88         return NULL;
89     }
90     deserializeInternal(inData, (Res_png_9patch*) inData);
91     return (Res_png_9patch*) inData;
92 }
93 
Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20(JNIEnv * env,jobject,long addr)94 extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20(JNIEnv * env, jobject, long addr)
95 {
96     Res_png_9patch20* chunk = reinterpret_cast<Res_png_9patch20*>(addr);
97     Res_png_9patch20::deserialize(chunk);
98     //printChunkInformation(chunk);
99     jintArray result;
100     size_t size = 3+chunk->numXDivs+chunk->numYDivs+chunk->numColors;
101     result = env->NewIntArray(size);
102     if (!result)
103         return 0;
104 
105     jint *data = (jint*)malloc(sizeof(jint)*size);
106     size_t pos = 0;
107     data[pos++] = chunk->numXDivs;
108     data[pos++] = chunk->numYDivs;
109     data[pos++] = chunk->numColors;
110 
111     int32_t* xDivs = chunk->getXDivs();
112     int32_t* yDivs = chunk->getYDivs();
113     uint32_t* colors = chunk->getColors();
114 
115     for (int x = 0; x <chunk->numXDivs; x ++)
116         data[pos++]=xDivs[x];
117     for (int y = 0; y <chunk->numYDivs; y ++)
118         data[pos++] = yDivs[y];
119     for (int c = 0; c <chunk->numColors; c ++)
120         data[pos++] = colors[c];
121     env->SetIntArrayRegion(result, 0, size, data);
122     free(data);
123     return result;
124 }
125 
Java_org_qtproject_qt5_android_ExtractStyle_extractChunkInfo20(JNIEnv * env,jobject obj,jbyteArray chunkObj)126 extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractChunkInfo20(JNIEnv * env, jobject  obj, jbyteArray chunkObj)
127 {
128     size_t chunkSize = env->GetArrayLength(chunkObj);
129     void* storage = alloca(chunkSize);
130     env->GetByteArrayRegion(chunkObj, 0, chunkSize,
131                             reinterpret_cast<jbyte*>(storage));
132 
133     if (!env->ExceptionCheck())
134         return Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20(env, obj, long(storage));
135     else
136         env->ExceptionClear();
137     return 0;
138 }
139 
fill9patchOffsets(Res_png_9patch20 * patch)140 static inline void fill9patchOffsets(Res_png_9patch20* patch) {
141     patch->xDivsOffset = sizeof(Res_png_9patch20);
142     patch->yDivsOffset = patch->xDivsOffset + (patch->numXDivs * sizeof(int32_t));
143     patch->colorsOffset = patch->yDivsOffset + (patch->numYDivs * sizeof(int32_t));
144 }
145 
deserialize(void * inData)146 Res_png_9patch20* Res_png_9patch20::deserialize(void* inData)
147 {
148     Res_png_9patch20* patch = reinterpret_cast<Res_png_9patch20*>(inData);
149     patch->wasDeserialized = true;
150     fill9patchOffsets(patch);
151     return patch;
152 }
153