// Copyright 2009 Google Inc. // // 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.
static void usage(constchar* message, ...) { if (message) {
va_list ap;
va_start(ap, message);
vfprintf(stderr, message, ap);
va_end(ap);
fprintf(stderr, "\n\n");
fprintf(stderr, "usage:\n");
}
fprintf(
stderr, "%s infile [--help | --encode | --encodeNoHeader | --decode] [--showDifference difffile] [-o outfile]\n",
gpExeName);
fprintf(stderr, "\tDefault is --encode\n");
fprintf(stderr, "\t\t--help print this usage information.\n");
fprintf(stderr, "\t\t--encode create an ETC1 file from a PNG file.\n");
fprintf(
stderr, "\t\t--encodeNoHeader create a raw ETC1 data file (without a header) from a PNG file.\n");
fprintf(stderr, "\t\t--decode create a PNG file from an ETC1 file.\n");
fprintf(stderr, "\t\t--showDifference difffile Write difference between original and encoded\n");
fprintf(stderr, "\t\t image to difffile. (Only valid when encoding).\n");
fprintf(stderr, "\tIf outfile is not specified, an outfile path is constructed from infile,\n");
fprintf(stderr, "\twith the apropriate suffix (.pkm or .png).\n"); exit(1);
}
// Return non-zero on error int fwrite_big_endian_uint16(png_uint_32 data, FILE* pOut) { if (fputc(0xff & (data >> 8), pOut) == EOF) { return -1;
} if (fputc(0xff & data, pOut) == EOF) { return -1;
} return0;
}
// Return non-zero on error int fread_big_endian_uint16(png_uint_32* data, FILE* pIn) { int a, b; if ((a = fgetc(pIn)) == EOF) { return -1;
} if ((b = fgetc(pIn)) == EOF) { return -1;
}
*data = ((0xff & a) << 8) | (0xff & b); return0;
}
// Read a PNG file into a contiguous buffer. // Returns non-zero if an error occurred. // caller has to delete[] *ppImageData when done with the image.
int read_PNG_File(constchar* pInput, etc1_byte** ppImageData,
etc1_uint32* pWidth, etc1_uint32* pHeight) {
FILE* pIn = NULL;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
png_infop end_info = NULL;
png_bytep* row_pointers = NULL; // Does not need to be deallocated.
png_uint_32 width = 0;
png_uint_32 height = 0;
png_uint_32 stride = 0; int result = -1;
etc1_byte* pSourceImage = 0;
if ((pIn = fopen(pInput, "rb")) == NULL) {
fprintf(stderr, "Could not open input file %s for reading: %d\n",
pInput, errno); gotoexit;
}
staticconst size_t PNG_HEADER_SIZE = 8;
png_byte pngHeader[PNG_HEADER_SIZE]; if (fread(pngHeader, 1, PNG_HEADER_SIZE, pIn) != PNG_HEADER_SIZE) {
fprintf(stderr, "Could not read PNG header from %s: %d\n", pInput,
errno); gotoexit;
}
if (png_sig_cmp(pngHeader, 0, PNG_HEADER_SIZE)) {
fprintf(stderr, "%s is not a PNG file.\n", pInput); gotoexit;
}
if (!(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
(png_voidp) NULL, user_error_fn, user_warning_fn))) {
fprintf(stderr, "Could not initialize png read struct.\n"); gotoexit;
}
if (!(info_ptr = png_create_info_struct(png_ptr))) {
fprintf(stderr, "Could not create info struct.\n"); gotoexit;
} if (!(end_info = png_create_info_struct(png_ptr))) {
fprintf(stderr, "Could not create end_info struct.\n"); gotoexit;
}
result = 0; exit: if (result) { delete[] pSourceImage;
} if (png_ptr) {
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
} if (pIn) {
fclose(pIn);
}
return result;
}
// Read a PNG file into a contiguous buffer. // Returns non-zero if an error occurred. // caller has to delete[] *ppImageData when done with the image. int readPKMFile(constchar* pInput, etc1_byte** ppImageData,
etc1_uint32* pWidth, etc1_uint32* pHeight) { int result = -1;
FILE* pIn = NULL;
etc1_byte header[ETC_PKM_HEADER_SIZE];
png_bytep pEncodedData = NULL;
png_bytep pImageData = NULL;
void multipleEncodeDecodeCheck(bool* pbEncodeDecodeSeen) { if (*pbEncodeDecodeSeen) {
usage("At most one occurrence of --encode --encodeNoHeader or --decode is allowed.\n");
}
*pbEncodeDecodeSeen = true;
}
for (int i = 1; i < argc; i++) { constchar* pArg = argv[i]; if (pArg[0] == '-') { char c = pArg[1]; switch (c) { case'o': if (pOutput != NULL) {
usage("Only one -o flag allowed.");
} if (i + 1 >= argc) {
usage("Expected outfile after -o");
}
pOutput = argv[++i]; break; case'-': if (strcmp(pArg, "--encode") == 0) {
multipleEncodeDecodeCheck(&bEncodeDecodeSeen);
bEncode = true;
bEncodeHeader = true;
} elseif (strcmp(pArg, "--encodeNoHeader") == 0) {
multipleEncodeDecodeCheck(&bEncodeDecodeSeen);
bEncode = true;
bEncodeHeader = false;
} elseif (strcmp(pArg, "--decode") == 0) {
multipleEncodeDecodeCheck(&bEncodeDecodeSeen);
} elseif (strcmp(pArg, "--showDifference") == 0) { if (bShowDifference) {
usage("Only one --showDifference option allowed.\n");
}
bShowDifference = true; if (i + 1 >= argc) {
usage("Expected difffile after --showDifference");
}
pDiffFile = argv[++i];
} elseif (strcmp(pArg, "--help") == 0) {
usage( NULL);
} else {
usage("Unknown flag %s", pArg);
}
break; default:
usage("Unknown flag %s", pArg); break;
}
} else { if (pInput != NULL) {
usage( "Only one input file allowed. Already have %s, now see %s",
pInput, pArg);
}
pInput = pArg;
}
}
if (!bEncodeDecodeSeen) {
bEncode = true;
bEncodeHeader = true;
} if ((! bEncode) && bShowDifference) {
usage("--showDifference is only valid when encoding.");
}
if (!pInput) {
usage("Expected an input file.");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.