LP64: Make 9 patches architecture agnostic.
The Res_png_9patch struct had several pointer members
whose size differed between 32 and 64 bit platforms.
These members have been replaced by uint32_t offsets
to serialized data. The serialized form for 9patches
places a Res_png_9patch object at the beginning of
serialized data, followed by int32_t arrays of xDivs,
yDivs and colors.
Note that these offsets are not strictly required,
since they can be computed from the values of numXDivs,
numYDivs & numColors, however they are called in tight
loops so having them computed once is a beneficial.
This change also removed the unused patch_equals function
from aapt's Image.cpp.
Change-Id: I3b9ac8ae5c05510d41377cae4dff1c69b40c2531
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 25a948d..db74831 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -35,7 +35,9 @@
// This holds an image as 8bpp RGBA.
struct image_info
{
- image_info() : rows(NULL), is9Patch(false), allocRows(NULL) { }
+ image_info() : rows(NULL), is9Patch(false),
+ xDivs(NULL), yDivs(NULL), colors(NULL), allocRows(NULL) { }
+
~image_info() {
if (rows && rows != allocRows) {
free(rows);
@@ -46,9 +48,15 @@
}
free(allocRows);
}
- free(info9Patch.xDivs);
- free(info9Patch.yDivs);
- free(info9Patch.colors);
+ free(xDivs);
+ free(yDivs);
+ free(colors);
+ }
+
+ void* serialize9patch() {
+ void* serialized = Res_png_9patch::serialize(info9Patch, xDivs, yDivs, colors);
+ reinterpret_cast<Res_png_9patch*>(serialized)->deviceToFile();
+ return serialized;
}
png_uint_32 width;
@@ -58,6 +66,9 @@
// 9-patch info.
bool is9Patch;
Res_png_9patch info9Patch;
+ int32_t* xDivs;
+ int32_t* yDivs;
+ uint32_t* colors;
// Layout padding, if relevant
bool haveLayoutBounds;
@@ -430,10 +441,10 @@
{
int left, right, top, bottom;
select_patch(
- hpatch, image->info9Patch.xDivs[0], image->info9Patch.xDivs[1],
+ hpatch, image->xDivs[0], image->xDivs[1],
image->width, &left, &right);
select_patch(
- vpatch, image->info9Patch.yDivs[0], image->info9Patch.yDivs[1],
+ vpatch, image->yDivs[0], image->yDivs[1],
image->height, &top, &bottom);
//printf("Selecting h=%d v=%d: (%d,%d)-(%d,%d)\n",
// hpatch, vpatch, left, top, right, bottom);
@@ -452,8 +463,8 @@
int maxSizeXDivs = W * sizeof(int32_t);
int maxSizeYDivs = H * sizeof(int32_t);
- int32_t* xDivs = image->info9Patch.xDivs = (int32_t*) malloc(maxSizeXDivs);
- int32_t* yDivs = image->info9Patch.yDivs = (int32_t*) malloc(maxSizeYDivs);
+ int32_t* xDivs = image->xDivs = (int32_t*) malloc(maxSizeXDivs);
+ int32_t* yDivs = image->yDivs = (int32_t*) malloc(maxSizeYDivs);
uint8_t numXDivs = 0;
uint8_t numYDivs = 0;
@@ -609,7 +620,7 @@
numColors = numRows * numCols;
image->info9Patch.numColors = numColors;
- image->info9Patch.colors = (uint32_t*)malloc(numColors * sizeof(uint32_t));
+ image->colors = (uint32_t*)malloc(numColors * sizeof(uint32_t));
// Fill in color information for each patch.
@@ -652,7 +663,7 @@
right = xDivs[i];
}
c = get_color(image->rows, left, top, right - 1, bottom - 1);
- image->info9Patch.colors[colorIndex++] = c;
+ image->colors[colorIndex++] = c;
NOISY(if (c != Res_png_9patch::NO_COLOR) hasColor = true);
left = right;
}
@@ -664,14 +675,10 @@
for (i=0; i<numColors; i++) {
if (hasColor) {
if (i == 0) printf("Colors in %s:\n ", imageName);
- printf(" #%08x", image->info9Patch.colors[i]);
+ printf(" #%08x", image->colors[i]);
if (i == numColors - 1) printf("\n");
}
}
-
- image->is9Patch = true;
- image->info9Patch.deviceToFile();
-
getout:
if (errorMsg) {
fprintf(stderr,
@@ -691,14 +698,10 @@
return NO_ERROR;
}
-static void checkNinePatchSerialization(Res_png_9patch* inPatch, void * data)
+static void checkNinePatchSerialization(Res_png_9patch* inPatch, void* data)
{
- if (sizeof(void*) != sizeof(int32_t)) {
- // can't deserialize on a non-32 bit system
- return;
- }
size_t patchSize = inPatch->serializedSize();
- void * newData = malloc(patchSize);
+ void* newData = malloc(patchSize);
memcpy(newData, data, patchSize);
Res_png_9patch* outPatch = inPatch->deserialize(newData);
// deserialization is done in place, so outPatch == newData
@@ -721,34 +724,6 @@
free(newData);
}
-static bool patch_equals(Res_png_9patch& patch1, Res_png_9patch& patch2) {
- if (!(patch1.numXDivs == patch2.numXDivs &&
- patch1.numYDivs == patch2.numYDivs &&
- patch1.numColors == patch2.numColors &&
- patch1.paddingLeft == patch2.paddingLeft &&
- patch1.paddingRight == patch2.paddingRight &&
- patch1.paddingTop == patch2.paddingTop &&
- patch1.paddingBottom == patch2.paddingBottom)) {
- return false;
- }
- for (int i = 0; i < patch1.numColors; i++) {
- if (patch1.colors[i] != patch2.colors[i]) {
- return false;
- }
- }
- for (int i = 0; i < patch1.numXDivs; i++) {
- if (patch1.xDivs[i] != patch2.xDivs[i]) {
- return false;
- }
- }
- for (int i = 0; i < patch1.numYDivs; i++) {
- if (patch1.yDivs[i] != patch2.yDivs[i]) {
- return false;
- }
- }
- return true;
-}
-
static void dump_image(int w, int h, png_bytepp rows, int color_type)
{
int i, j, rr, gg, bb, aa;
@@ -1061,7 +1036,7 @@
: (png_byte*)"npTc";
NOISY(printf("Adding 9-patch info...\n"));
strcpy((char*)unknowns[p_index].name, "npTc");
- unknowns[p_index].data = (png_byte*)imageInfo.info9Patch.serialize();
+ unknowns[p_index].data = (png_byte*)imageInfo.serialize9patch();
unknowns[p_index].size = imageInfo.info9Patch.serializedSize();
// TODO: remove the check below when everything works
checkNinePatchSerialization(&imageInfo.info9Patch, unknowns[p_index].data);