+ int iFormatID = convertImportFormatNameToID (pszFormat);
+
+ if (iFormatID == IMPORT_FORMAT_PPM)
+ return readImagePPM (pszFilename);
+#ifdef HAVE_PNG
+ else if (iFormatID == IMPORT_FORMAT_PNG)
+ return readImagePNG (pszFilename);
+#endif
+
+ sys_error (ERR_SEVERE, "Invalid format %s [ImageFile::importImage]", pszFormat);
+ return false;
+}
+
+void
+ImageFile::skipSpacePPM (FILE* fp)
+{
+ int c = fgetc (fp);
+ while (isspace (c) || c == '#') {
+ if (c == '#') { // comment until end of line
+ c = fgetc(fp);
+ while (c != 13 && c != 10)
+ c = fgetc(fp);
+ }
+ else
+ c = fgetc(fp);
+ }
+
+ ungetc (c, fp);
+}
+
+bool
+ImageFile::readImagePPM (const char* const pszFile)
+{
+ FILE* fp = fopen (pszFile, "r");
+ if ((fp = fopen (pszFile, "r")) == NULL)
+ return false;
+ char cSignature = toupper(fgetc(fp));
+ if (cSignature != 'P') {
+ fclose(fp);
+ return false;
+ }
+ cSignature = fgetc(fp);
+ if (cSignature == '5' || cSignature == '6') { // binary modes
+ fclose(fp);
+ fp = fopen(pszFile, "rb"); // reopen in binary mode
+ fgetc(fp);
+ fgetc(fp);
+ } else if (cSignature != '2' && cSignature != '3') {
+ fclose(fp);
+ return false;
+ }
+
+ int nRows, nCols, iMaxValue;
+ skipSpacePPM (fp);
+ if (fscanf (fp, "%d", &nCols) != 1) {
+ fclose(fp);
+ return false;
+ }
+ skipSpacePPM (fp);
+ if (fscanf (fp, "%d", &nRows) != 1) {
+ fclose(fp);
+ return false;
+ }
+ skipSpacePPM (fp);
+ if (fscanf (fp, "%d", &iMaxValue) != 1) {
+ fclose(fp);
+ return false;
+ }
+ setArraySize (nRows, nCols);
+
+ if (cSignature == '5' || cSignature == '6') { // binary modes
+ int c = fgetc(fp);
+ if (c == 13) {
+ c = fgetc(fp);
+ if (c != 10) // read msdos 13-10 newline
+ ungetc(c, fp);
+ }
+ } else
+ skipSpacePPM (fp); // ascii may have comments
+
+ double dMaxValue = iMaxValue;
+ ImageFileArray v = getArray();
+ for (int iy = nRows - 1; iy >= 0; iy--) {
+ for (int ix = 0; ix < nCols; ix++) {
+ int iGS, iR, iG, iB;
+ double dR, dG, dB;
+ switch (cSignature) {
+ case '2':
+ if (fscanf(fp, "%d ", &iGS) != 1) {
+ fclose(fp);
+ return false;
+ }
+ v[ix][iy] = iGS / dMaxValue;
+ break;
+ case '5':
+ iGS = fgetc(fp);
+ if (iGS == EOF) {
+ fclose(fp);
+ return false;
+ }
+ v[ix][iy] = iGS / dMaxValue;
+ break;
+ case '3':
+ if (fscanf (fp, "%d %d %d ", &iR, &iG, &iB) != 3) {
+ fclose(fp);
+ return false;
+ }
+ dR = iR / dMaxValue;
+ dG = iG / dMaxValue;
+ dB = iB / dMaxValue;
+ v[ix][iy] = colorToGrayscale (dR, dG, dB);
+ break;
+ case '6':
+ iR = fgetc(fp);
+ iG = fgetc(fp);
+ iB = fgetc(fp);
+ if (iB == EOF) {
+ fclose(fp);
+ return false;
+ }
+ dR = iR / dMaxValue;
+ dG = iG / dMaxValue;
+ dB = iB / dMaxValue;
+ v[ix][iy] = colorToGrayscale (dR, dG, dB);
+ break;
+ }
+ }
+ }
+
+ fclose(fp);
+ return true;
+}
+
+#ifdef HAVE_PNG
+bool
+ImageFile::readImagePNG (const char* const pszFile)
+{
+ FILE* fp = fopen(pszFile, "rb");
+ if (!fp)
+ return false;
+ unsigned char header[8];
+ fread (header, 1, 8, fp);
+ if (png_sig_cmp (header, 0, 8)) {
+ fclose (fp);
+ return false;
+ }
+
+ png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr) {
+ fclose(fp);
+ return false;
+ }
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+ fclose(fp);
+ return false;
+ }
+
+ png_infop end_info = png_create_info_struct(png_ptr);
+ if (!end_info) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ fclose(fp);