/* * Process a regular file, adding it to the archive if appropriate. * * This function is intended for use when creating a cached overlay package. * Only xml and .9.png files are processed and added to the package. * * If we're in "update" mode, and the file already exists in the archive, * delete the existing entry before adding the new one. */ bool processOverlayFile(Bundle* bundle, ZipFile* zip, String8 storageName, const sp<const AaptFile>& file) { const bool hasData = file->hasData(); storageName.convertToResPath(); ZipEntry* entry; bool fromGzip = false; status_t result; if (strcasecmp(storageName.getPathExtension().string(), ".gz") == 0) { fromGzip = true; storageName = storageName.getBasePath(); } if (bundle->getUpdate()) { entry = zip->getEntryByName(storageName.string()); if (entry != NULL) { /* file already exists in archive; there can be only one */ if (entry->getMarked()) { fprintf(stderr, "ERROR: '%s' exists twice (check for with & w/o '.gz'?)\n", file->getPrintableSource().string()); return false; } zip->remove(entry); } } if (hasData) { const char* name = storageName.string(); if (endsWith(name, ".9.png") || endsWith(name, ".xml") || endsWith(name, ".arsc")) { result = zip->add(file->getData(), file->getSize(), storageName.string(), file->getCompressionMethod(), &entry); if (result == NO_ERROR) { if (bundle->getVerbose()) { printf(" '%s'%s", storageName.string(), fromGzip ? " (from .gz)" : ""); if (entry->getCompressionMethod() == ZipEntry::kCompressStored) { printf(" (not compressed)\n"); } else { printf(" (compressed %d%%)\n", calcPercent(entry->getUncompressedLen(), entry->getCompressedLen())); } } entry->setMarked(true); } else { if (result == ALREADY_EXISTS) { fprintf(stderr, " Unable to add '%s': file already in archive (try '-u'?)\n", file->getPrintableSource().string()); } else { fprintf(stderr, " Unable to add '%s': Zip add failed\n", file->getPrintableSource().string()); } return false; } } } return true; }
/* * Process a regular file, adding it to the archive if appropriate. * * If we're in "update" mode, and the file already exists in the archive, * delete the existing entry before adding the new one. */ bool processFile(Bundle* bundle, ZipFile* zip, String8 storageName, const sp<const AaptFile>& file) { const bool hasData = file->hasData(); ZipEntry* entry; bool fromGzip = false; status_t result; /* * See if the filename ends in ".EXCLUDE". We can't use * String8::getPathExtension() because the length of what it considers * to be an extension is capped. * * The Asset Manager doesn't check for ".EXCLUDE" in Zip archives, * so there's no value in adding them (and it makes life easier on * the AssetManager lib if we don't). * * NOTE: this restriction has been removed. If you're in this code, you * should clean this up, but I'm in here getting rid of Path Name, and I * don't want to make other potentially breaking changes --joeo */ int fileNameLen = storageName.length(); int excludeExtensionLen = strlen(kExcludeExtension); if (fileNameLen > excludeExtensionLen && (0 == strcmp(storageName.string() + (fileNameLen - excludeExtensionLen), kExcludeExtension))) { fprintf(stderr, "warning: '%s' not added to Zip\n", storageName.string()); return true; } if (strcasecmp(storageName.getPathExtension().string(), ".gz") == 0) { fromGzip = true; storageName = storageName.getBasePath(); } if (bundle->getUpdate()) { entry = zip->getEntryByName(storageName.string()); if (entry != NULL) { /* file already exists in archive; there can be only one */ if (entry->getMarked()) { fprintf(stderr, "ERROR: '%s' exists twice (check for with & w/o '.gz'?)\n", file->getPrintableSource().string()); return false; } if (!hasData) { const String8& srcName = file->getSourceFile(); time_t fileModWhen; fileModWhen = getFileModDate(srcName.string()); if (fileModWhen == (time_t) -1) { // file existence tested earlier, return false; // not expecting an error here } if (fileModWhen > entry->getModWhen()) { // mark as deleted so add() will succeed if (bundle->getVerbose()) { printf(" (removing old '%s')\n", storageName.string()); } zip->remove(entry); } else { // version in archive is newer if (bundle->getVerbose()) { printf(" (not updating '%s')\n", storageName.string()); } entry->setMarked(true); return true; } } else { // Generated files are always replaced. zip->remove(entry); } } } //android_setMinPriority(NULL, ANDROID_LOG_VERBOSE); if (fromGzip) { result = zip->addGzip(file->getSourceFile().string(), storageName.string(), &entry); } else if (!hasData) { /* don't compress certain files, e.g. PNGs */ int compressionMethod = bundle->getCompressionMethod(); if (!okayToCompress(bundle, storageName)) { compressionMethod = ZipEntry::kCompressStored; } result = zip->add(file->getSourceFile().string(), storageName.string(), compressionMethod, &entry); } else { result = zip->add(file->getData(), file->getSize(), storageName.string(), file->getCompressionMethod(), &entry); } if (result == NO_ERROR) { if (bundle->getVerbose()) { printf(" '%s'%s", storageName.string(), fromGzip ? " (from .gz)" : ""); if (entry->getCompressionMethod() == ZipEntry::kCompressStored) { printf(" (not compressed)\n"); } else { printf(" (compressed %d%%)\n", calcPercent(entry->getUncompressedLen(), entry->getCompressedLen())); } } entry->setMarked(true); } else { if (result == ALREADY_EXISTS) { fprintf(stderr, " Unable to add '%s': file already in archive (try '-u'?)\n", file->getPrintableSource().string()); } else { fprintf(stderr, " Unable to add '%s': Zip add failed (%d)\n", file->getPrintableSource().string(), result); } return false; } return true; }
status_t AaptAssets::addIncludedResources(const sp<AaptFile>& file) { const ResTable& res = getIncludedResources(); // XXX dirty! return const_cast<ResTable&>(res).add(file->getData(), file->getSize(), NULL); }
// Next collect all remainibng strings. collect_strings(&strings, &resids, stripComments, stripRawValues); #if 0 // No longer compiles NOISY(printf("Found strings:\n"); const size_t N = strings.size(); for (size_t i=0; i<N; i++) { printf("%s\n", String8(strings.entryAt(i).string).string()); } ); #endif sp<AaptFile> stringPool = strings.createStringBlock(); NOISY(aout << "String pool:" << HexDump(stringPool->getData(), stringPool->getSize()) << endl); ResXMLTree_header header; memset(&header, 0, sizeof(header)); header.header.type = htods(RES_XML_TYPE); header.header.headerSize = htods(sizeof(header)); const size_t basePos = dest->getSize(); dest->writeData(&header, sizeof(header)); dest->writeData(stringPool->getData(), stringPool->getSize()); // If we have resource IDs, write them. if (resids.size() > 0) { const size_t resIdsPos = dest->getSize(); const size_t resIdsSize = sizeof(ResChunk_header)+(sizeof(uint32_t)*resids.size());
int V4L2JpegEncoder::buildExif(sp<Buffer> exifData, sp<Buffer> thumbData) { uint8_t *ptr = exifData->getData(); uint8_t *tiffHeader; uint8_t *app1size; uint16_t size; TRACE(); memcpy(ptr, APP1_MARKER, sizeof(APP1_MARKER)); ptr += sizeof(APP1_MARKER); app1size = ptr; ptr += 2; memcpy(ptr, EXIF_HEADER, sizeof(EXIF_HEADER)); ptr += sizeof(EXIF_HEADER); tiffHeader = ptr; memcpy(ptr, TIFF_HEADER, sizeof(TIFF_HEADER)); ptr += sizeof(TIFF_HEADER); ExifIfd ifd0(ptr, ARRAY_SIZE(exifIfd0TagMap) + 3 + !!gpsData, ptr - tiffHeader); for (uint32_t i = 0; i < ARRAY_SIZE(exifIfd0TagMap); ++i) pushIfdTag(ifd0, exifIfd0TagMap[i].key, exifIfd0TagMap[i].tag); ptr += ifd0.size(); ifd0.push(EXIF_TAG_IMAGE_WIDTH, input.width); ifd0.push(EXIF_TAG_IMAGE_HEIGHT, input.height); ifd0.push(EXIF_TAG_EXIF_IFD_POINTER, (uint32_t)(ptr - tiffHeader)); ExifIfd ifdExif(ptr, ARRAY_SIZE(exifIfdExifTagMap), ptr - tiffHeader); for (uint32_t i = 0; i < ARRAY_SIZE(exifIfdExifTagMap); ++i) pushIfdTag(ifdExif, exifIfdExifTagMap[i].key, exifIfdExifTagMap[i].tag); ptr += ifdExif.size(); if (gpsData) { ifd0.push(EXIF_TAG_GPS_IFD_POINTER, (uint32_t)(ptr - tiffHeader)); ExifIfd ifdGps(ptr, 9, ptr - tiffHeader); ifdGps.push(EXIF_TAG_GPS_VERSION_ID, EXIF_TYPE_BYTE, 4, gpsData->versionId); ifdGps.push(EXIF_TAG_GPS_LATITUDE_REF, EXIF_TYPE_ASCII, 2, gpsData->latitudeRef); ifdGps.push(EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL, 3, gpsData->latitude); ifdGps.push(EXIF_TAG_GPS_LONGITUDE_REF, EXIF_TYPE_ASCII, 2, gpsData->longitudeRef); ifdGps.push(EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL, 3, gpsData->longitude); ifdGps.push(EXIF_TAG_GPS_ALTITUDE_REF, (uint8_t)gpsData->altitudeRef); ifdGps.push(EXIF_TAG_GPS_ALTITUDE, &gpsData->altitude); ifdGps.push(EXIF_TAG_GPS_TIMESTAMP, EXIF_TYPE_RATIONAL, 3, gpsData->timestamp); ifdGps.push(EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII, 11, gpsData->datestamp); ptr += ifdGps.size(); } if (thumbData != 0) { ifd0.link(ptr - tiffHeader); ExifIfd ifd1(ptr, ARRAY_SIZE(exifIfd1TagMap) + 5 , ptr - tiffHeader); ifd1.push(EXIF_TAG_IMAGE_WIDTH, (uint32_t)thumbnail.width); ifd1.push(EXIF_TAG_IMAGE_HEIGHT, (uint32_t)thumbnail.height); ifd1.push(EXIF_TAG_COMPRESSION_SCHEME, (uint16_t)EXIF_DEF_COMPRESSION); for (uint32_t i = 0; i < ARRAY_SIZE(exifIfd1TagMap); ++i) pushIfdTag(ifdExif, exifIfd1TagMap[i].key, exifIfd1TagMap[i].tag); ptr += ifd1.size(); ifd1.push(EXIF_TAG_JPEG_INTERCHANGE_FORMAT, (uint32_t)(ptr - tiffHeader)); ifd1.push(EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, thumbData->getSize()); memcpy(ptr, thumbData->getData(), thumbData->getSize()); ptr += thumbData->getSize(); } size = ptr - app1size; app1size[0] = size >> 8; app1size[1] = size & 0xff; return ptr - exifData->getData(); }