/* * The Npic library * * Copyright (C) 2003 Edouard Thiel * * This library is free software under the terms of the * GNU Lesser General Public License (LGPL) version 2.1. */ /* DO NOT EDIT !!! Generated by npic-templa from "files_npz.ct" */ /* * files_npz.c - 17/12/2008 * * File format NPZ */ #include #define MAXBUF 65536 /*--------------------- P U B L I C - I N T E R F A C E ----------------------*/ /* * Write file in NPZ format * Only interior pixels are saved. * Do nothing if image is not ok. * Return NPIC_SUCCESS, else error code. Verbose. * * USAGE : * Npic_image *np; int err; * ... * err = NpicWriteNPZ (np, "example.npz"); * if (err < 0) return err; * .... * NpicDestroyImage (np); */ int NpicWriteNPZ (Npic_image *np, const char *filename) { FILE *f1; int res; Npic_file_gz fgz; if (NpicImageIsOK (np, __func__) != NPIC_SUCCESS) return NPIC_ERR_NOT_OK; /* * Open file in binary write mode, so '\n' is 1 char. */ f1 = fopen (filename, "wb"); if (f1 == NULL) return NpicError (__func__, NPIC_ERR_OPEN, ": file \"%s\"", filename); /* Write header, then close. */ res = NpicWriteNPZHeader (np, f1); fclose (f1); if (res != NPIC_SUCCESS) return NpicError (__func__, res, ": file \"%s\"", filename); /* Now write compressed datas */ NpicWriteGZ_Open (&fgz, filename, __func__, 1, NPIC_COMPRESS_GZ); if (fgz.res == NPIC_SUCCESS) fgz.res = NpicWriteNPZDatas (np, fgz.f2); NpicWriteGZ_Close (&fgz); return NpicError (__func__, fgz.res, ": file \"%s\"", filename); } /* * Read file in NPZ format. * * Return image on success, else return NULL. Verbose. * * USAGE : * Npic_image *np; * np = NpicReadNPZ ("example.npz"); * if (np == NULL) return; * .... * NpicDestroyImage (np); */ Npic_image *NpicReadNPZ (const char *filename) { Npic_image *np; FILE *f1; Npic_npz_info h1; Npic_file_gz fgz; int res, pos; /* Open file in binary read mode */ f1 = fopen (filename, "rb"); if (f1 == NULL) { NpicError (__func__, NPIC_ERR_OPEN, ": file \"%s\"", filename); return NULL; } res = NpicNPZReadInfo (f1, &h1); if (res < 0) { fclose (f1); NpicError (__func__, res, ": file \"%s\"", filename); return NULL; } /* Now we might have props in h1, which has to be freed on error */ /* Get current position in file, then close */ pos = ftell (f1); fclose (f1); if (pos < 0) { NpicError (__func__, NPIC_ERR_GETPOS, ": file \"%s\"", filename); NpicFreeProps (&h1.props); return NULL; } np = NpicCreateImageForNPZ (&h1); if (np == NULL) { NpicError (__func__, NPIC_ERROR, ": file \"%s\"", filename); NpicFreeProps (&h1.props); return NULL; } /* We put h1.props in np->gen.props (which was empty before); the properties will be freed on np destruction. */ memmove (&np->gen.props, &h1.props, sizeof(Npic_props)); /* Now read compressed datas */ NpicReadGZ_Open (&fgz, filename, __func__, pos, NPIC_COMPRESS_GZ); if (fgz.res == NPIC_SUCCESS) fgz.res = NpicReadNPZDatas (np, fgz.f2); NpicReadGZ_Close (&fgz); if (fgz.res != NPIC_SUCCESS) { NpicDestroyImage (np); np = NULL; NpicError (__func__, fgz.res, ": file \"%s\"", filename); } return np; } /* * Print infos of a file in NPZ format * * Return NPIC_SUCCESS, else error code. Verbose. */ int NpicInfoNPZ (const char *filename) { Npic_file_gz fgz; Npic_npz_info info; NpicReadGZ_Open (&fgz, filename, __func__, 0, 0); if (fgz.res == NPIC_SUCCESS) { fgz.res = NpicNPZReadInfo (fgz.f2, &info); if (fgz.res == NPIC_SUCCESS) fgz.res = NpicNPZPrintInfo (filename, &info); NpicError (__func__, fgz.res, ": file \"%s\"", filename); NpicFreeProps (&info.props); } NpicReadGZ_Close (&fgz); return fgz.res; } /*-------------------- P R I V A T E - F U N C T I O N S ---------------------*/ /* * Write header of a file in NPZ format. * * Return NPIC_SUCCESS, else error code. Silent. */ int NpicWriteNPZHeader (Npic_image *np, FILE *f) { time_t tm; int i; if (np == NULL) return NPIC_ERR_NULL_PTR; if (f == NULL) return NPIC_ERR_BAD_FD; fprintf (f, "NPZ-11\n"); fprintf (f, "# Image file generated by libNpic - "); time(&tm); fprintf (f, "%s", ctime(&tm)); fprintf (f, "TYPE "); switch (np->type) { case NPIC_IMAGE_2C : fprintf (f, "NPIC_IMAGE_2C\n"); break; case NPIC_IMAGE_2L : fprintf (f, "NPIC_IMAGE_2L\n"); break; case NPIC_IMAGE_2D : fprintf (f, "NPIC_IMAGE_2D\n"); break; case NPIC_IMAGE_2Q : fprintf (f, "NPIC_IMAGE_2Q\n"); break; case NPIC_IMAGE_3C : fprintf (f, "NPIC_IMAGE_3C\n"); break; case NPIC_IMAGE_3L : fprintf (f, "NPIC_IMAGE_3L\n"); break; case NPIC_IMAGE_3D : fprintf (f, "NPIC_IMAGE_3D\n"); break; case NPIC_IMAGE_3Q : fprintf (f, "NPIC_IMAGE_3Q\n"); break; case NPIC_IMAGE_4C : fprintf (f, "NPIC_IMAGE_4C\n"); break; case NPIC_IMAGE_4L : fprintf (f, "NPIC_IMAGE_4L\n"); break; case NPIC_IMAGE_4D : fprintf (f, "NPIC_IMAGE_4D\n"); break; case NPIC_IMAGE_4Q : fprintf (f, "NPIC_IMAGE_4Q\n"); break; case NPIC_IMAGE_5C : fprintf (f, "NPIC_IMAGE_5C\n"); break; case NPIC_IMAGE_5L : fprintf (f, "NPIC_IMAGE_5L\n"); break; case NPIC_IMAGE_5D : fprintf (f, "NPIC_IMAGE_5D\n"); break; case NPIC_IMAGE_5Q : fprintf (f, "NPIC_IMAGE_5Q\n"); break; case NPIC_IMAGE_6C : fprintf (f, "NPIC_IMAGE_6C\n"); break; case NPIC_IMAGE_6L : fprintf (f, "NPIC_IMAGE_6L\n"); break; case NPIC_IMAGE_6D : fprintf (f, "NPIC_IMAGE_6D\n"); break; case NPIC_IMAGE_6Q : fprintf (f, "NPIC_IMAGE_6Q\n"); break; default : fprintf (f, "ERROR\n"); break; } fprintf (f, "COMP GZIP\n"); fprintf (f, "XMAX %d\n", np->gen.xmax); fprintf (f, "YMAX %d\n", np->gen.ymax); if (np->gen.dim >= 3) fprintf (f, "ZMAX %d\n", np->gen.zmax); if (np->gen.dim >= 4) fprintf (f, "TMAX %d\n", np->gen.tmax); if (np->gen.dim >= 5) fprintf (f, "SMAX %d\n", np->gen.smax); if (np->gen.dim >= 6) fprintf (f, "RMAX %d\n", np->gen.rmax); /* New in NPZ-11: we write properties */ for (i = 0; i < np->gen.props.nb; i++) fprintf (f, "PROP %s: %s\n", np->gen.props.list[i].key, np->gen.props.list[i].val); fprintf (f, "DATA\n"); return NPIC_SUCCESS; } /* * Write binary datas in f. * * Return NPIC_SUCCESS, else error code. Silent. */ int NpicWriteNPZDatas (Npic_image *np, FILE *f) { if (np == NULL) return NPIC_ERR_NULL_PTR; if (f == NULL) return NPIC_ERR_BAD_FD; /* First, write a test value */ switch (np->type) { case NPIC_IMAGE_2L : case NPIC_IMAGE_3L : case NPIC_IMAGE_4L : case NPIC_IMAGE_5L : case NPIC_IMAGE_6L : { Npic_l h = NPIC_TEST32; if (fwrite (&h, sizeof(h), 1, f) <= 0) return NPIC_ERR_WRITE; } break; case NPIC_IMAGE_2D : case NPIC_IMAGE_3D : case NPIC_IMAGE_4D : case NPIC_IMAGE_5D : case NPIC_IMAGE_6D : { Npic_d h = NPIC_TESTDBL; if (fwrite (&h, sizeof(h), 1, f) <= 0) return NPIC_ERR_WRITE; } break; case NPIC_IMAGE_2Q : case NPIC_IMAGE_3Q : case NPIC_IMAGE_4Q : case NPIC_IMAGE_5Q : case NPIC_IMAGE_6Q : { Npic_uint16 h = NPIC_TEST16; if (fwrite (&h, sizeof(h), 1, f) <= 0) return NPIC_ERR_WRITE; } break; } /* Second, write the raw binary image */ return NpicWriteRAW (np, f, 0); } /* * Read infos (i.e text header) of a file in NPZ format. * then store results in struct info. * The file is already fopen. * Return NPIC_SUCCESS, else error code. Silent in many cases. * On success, properties have to be freed with NpicPropsFree. */ int NpicNPZReadInfo (FILE *f, Npic_npz_info *info) { char buf[MAXBUF], tok[32]; if (f == NULL) return NPIC_ERR_BAD_FD; if (info == NULL) return NPIC_ERR_NULL_PTR; /* Init */ info->version = -1; info->type = info->comp = info->dim = -1; info->xmax = info->ymax = info->zmax = -1; info->tmax = info->smax = info->rmax = -1; NpicInitProps (&info->props); /* Read MagicValue */ if (fscanf (f, "%4s", buf) <= 0) return NPIC_ERR_HEADER; if (strncmp (buf, "NPZ-", 4) != 0) return NPIC_ERR_MAGIC; /* Read version on same line */ if (fscanf (f, "%d", &info->version) <= 0) return NPIC_ERR_HEADER; if (info->version < 10 || info->version > 11) return NPIC_ERR_VERSION; /* * Read tokens and values in header */ while (1) { /* Ignore a comment; see NpicPNMReadInt() */ if (fscanf (f, " %1[#]%*[^\n]\n", tok) > 0) continue; /* Read token */ if (fscanf (f, "%30s", tok) == 1) { if (strcmp (tok, "TYPE") == 0) { if (fscanf (f, "%30s", buf) == 1) { if (strcmp (buf, "NPIC_IMAGE_2C") == 0) { info->type = NPIC_IMAGE_2C; info->dim = 2; } else if (strcmp (buf, "NPIC_IMAGE_2L") == 0) { info->type = NPIC_IMAGE_2L; info->dim = 2; } else if (strcmp (buf, "NPIC_IMAGE_2D") == 0) { info->type = NPIC_IMAGE_2D; info->dim = 2; } else if (strcmp (buf, "NPIC_IMAGE_2Q") == 0) { info->type = NPIC_IMAGE_2Q; info->dim = 2; } else if (strcmp (buf, "NPIC_IMAGE_3C") == 0) { info->type = NPIC_IMAGE_3C; info->dim = 3; } else if (strcmp (buf, "NPIC_IMAGE_3L") == 0) { info->type = NPIC_IMAGE_3L; info->dim = 3; } else if (strcmp (buf, "NPIC_IMAGE_3D") == 0) { info->type = NPIC_IMAGE_3D; info->dim = 3; } else if (strcmp (buf, "NPIC_IMAGE_3Q") == 0) { info->type = NPIC_IMAGE_3Q; info->dim = 3; } else if (strcmp (buf, "NPIC_IMAGE_4C") == 0) { info->type = NPIC_IMAGE_4C; info->dim = 4; } else if (strcmp (buf, "NPIC_IMAGE_4L") == 0) { info->type = NPIC_IMAGE_4L; info->dim = 4; } else if (strcmp (buf, "NPIC_IMAGE_4D") == 0) { info->type = NPIC_IMAGE_4D; info->dim = 4; } else if (strcmp (buf, "NPIC_IMAGE_4Q") == 0) { info->type = NPIC_IMAGE_4Q; info->dim = 4; } else if (strcmp (buf, "NPIC_IMAGE_5C") == 0) { info->type = NPIC_IMAGE_5C; info->dim = 5; } else if (strcmp (buf, "NPIC_IMAGE_5L") == 0) { info->type = NPIC_IMAGE_5L; info->dim = 5; } else if (strcmp (buf, "NPIC_IMAGE_5D") == 0) { info->type = NPIC_IMAGE_5D; info->dim = 5; } else if (strcmp (buf, "NPIC_IMAGE_5Q") == 0) { info->type = NPIC_IMAGE_5Q; info->dim = 5; } else if (strcmp (buf, "NPIC_IMAGE_6C") == 0) { info->type = NPIC_IMAGE_6C; info->dim = 6; } else if (strcmp (buf, "NPIC_IMAGE_6L") == 0) { info->type = NPIC_IMAGE_6L; info->dim = 6; } else if (strcmp (buf, "NPIC_IMAGE_6D") == 0) { info->type = NPIC_IMAGE_6D; info->dim = 6; } else if (strcmp (buf, "NPIC_IMAGE_6Q") == 0) { info->type = NPIC_IMAGE_6Q; info->dim = 6; } if (info->type != -1) continue; } } else if (strcmp (tok, "INFO") == 0) { /* In NPZ-11, INFO is ignored ; we just read the end of the line */ if (fgets (buf, MAXBUF, f) != NULL) continue; } else if (strcmp (tok, "XMAX") == 0) { if (fscanf (f, "%d", &info->xmax) == 1) continue; } else if (strcmp (tok, "YMAX") == 0) { if (fscanf (f, "%d", &info->ymax) == 1) continue; } else if (strcmp (tok, "ZMAX") == 0) { if (fscanf (f, "%d", &info->zmax) == 1) continue; } else if (strcmp (tok, "TMAX") == 0) { if (fscanf (f, "%d", &info->tmax) == 1) continue; } else if (strcmp (tok, "SMAX") == 0) { if (fscanf (f, "%d", &info->smax) == 1) continue; } else if (strcmp (tok, "RMAX") == 0) { if (fscanf (f, "%d", &info->rmax) == 1) continue; } else if (strcmp (tok, "COMP") == 0) { if (fscanf (f, "%30s", buf) == 1) { if (strcmp (buf, "GZIP") == 0) info->comp = NPIC_NPZ_GZIP; if (info->comp != -1) continue; } } else if (strcmp (tok, "PROP") == 0) { /* The line we expect after "PROP" is " key: val\n". */ /* Jump one space */ if (fscanf (f, "%*c") == EOF) ; /* Read property and store it */ if (NpicPropRead (&info->props, f, NULL) == NPIC_SUCCESS) continue; } else if (strcmp (tok, "DATA") == 0) { /* After the header there is exactly one char to read before binary datas. The '*' in fscanf suppresses assignment */ if (fscanf (f, "%*c") == EOF) ; break; /* stop loop */ } } /* Bad header */ NpicFreeProps (&info->props); return NPIC_ERR_HEADER; } return NPIC_SUCCESS; } /* * Read binary datas from f. * * Return NPIC_SUCCESS, else error code. Silent. */ int NpicReadNPZDatas (Npic_image *np, FILE *f1) { int swap = 0; if (np == NULL) return NPIC_ERR_NULL_PTR; if (f1 == NULL) return NPIC_ERR_BAD_FD; /* First, read test value and check if bytes should be swapped */ switch (np->type) { case NPIC_IMAGE_2L : case NPIC_IMAGE_3L : case NPIC_IMAGE_4L : case NPIC_IMAGE_5L : case NPIC_IMAGE_6L : { Npic_l h; if (fread (&h, sizeof(h), 1, f1) != 1) return NPIC_ERR_READ; if (h != NPIC_TEST32) { swap = 1; if (NPIC_BSWAP32(h) != NPIC_TEST32) return NPIC_ERR_ENDIAN; } } break; case NPIC_IMAGE_2D : case NPIC_IMAGE_3D : case NPIC_IMAGE_4D : case NPIC_IMAGE_5D : case NPIC_IMAGE_6D : { Npic_d h; union { Npic_d f; long long i; } u; if (fread (&h, sizeof(h), 1, f1) != 1) return NPIC_ERR_READ; if (h != NPIC_TESTDBL) { swap = 1; u.f = h; u.i = NPIC_BSWAP64(u.i); if (u.f != NPIC_TESTDBL) return NPIC_ERR_FLOAT; } } break; case NPIC_IMAGE_2Q : case NPIC_IMAGE_3Q : case NPIC_IMAGE_4Q : case NPIC_IMAGE_5Q : case NPIC_IMAGE_6Q : { Npic_uint16 h; if (fread (&h, sizeof(h), 1, f1) != 1) return NPIC_ERR_READ; if (h != NPIC_TEST16) { swap = 1; if (NPIC_BSWAP16(h) != NPIC_TEST16) return NPIC_ERR_ENDIAN; } } break; } /* Second, read raw binary image */ return NpicReadRAW (np, f1, swap); } /* * Create Npic_image image from NPZ header. * * Return image on success, else return NULL. Verbose. */ Npic_image *NpicCreateImageForNPZ (Npic_npz_info *info) { if (info == NULL) return NULL; switch (info->type) { case NPIC_IMAGE_2C : return NpicCreateImage_2c ( info->ymax, info->xmax, 0, 0); case NPIC_IMAGE_2L : return NpicCreateImage_2l ( info->ymax, info->xmax, 0, 0); case NPIC_IMAGE_2D : return NpicCreateImage_2d ( info->ymax, info->xmax, 0, 0); case NPIC_IMAGE_2Q : return NpicCreateImage_2q ( info->ymax, info->xmax, 0, 0); case NPIC_IMAGE_3C : return NpicCreateImage_3c ( info->zmax, info->ymax, info->xmax, 0, 0, 0); case NPIC_IMAGE_3L : return NpicCreateImage_3l ( info->zmax, info->ymax, info->xmax, 0, 0, 0); case NPIC_IMAGE_3D : return NpicCreateImage_3d ( info->zmax, info->ymax, info->xmax, 0, 0, 0); case NPIC_IMAGE_3Q : return NpicCreateImage_3q ( info->zmax, info->ymax, info->xmax, 0, 0, 0); case NPIC_IMAGE_4C : return NpicCreateImage_4c ( info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0); case NPIC_IMAGE_4L : return NpicCreateImage_4l ( info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0); case NPIC_IMAGE_4D : return NpicCreateImage_4d ( info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0); case NPIC_IMAGE_4Q : return NpicCreateImage_4q ( info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0); case NPIC_IMAGE_5C : return NpicCreateImage_5c ( info->smax, info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0, 0); case NPIC_IMAGE_5L : return NpicCreateImage_5l ( info->smax, info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0, 0); case NPIC_IMAGE_5D : return NpicCreateImage_5d ( info->smax, info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0, 0); case NPIC_IMAGE_5Q : return NpicCreateImage_5q ( info->smax, info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0, 0); case NPIC_IMAGE_6C : return NpicCreateImage_6c ( info->rmax, info->smax, info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0, 0, 0); case NPIC_IMAGE_6L : return NpicCreateImage_6l ( info->rmax, info->smax, info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0, 0, 0); case NPIC_IMAGE_6D : return NpicCreateImage_6d ( info->rmax, info->smax, info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0, 0, 0); case NPIC_IMAGE_6Q : return NpicCreateImage_6q ( info->rmax, info->smax, info->tmax, info->zmax, info->ymax, info->xmax, 0, 0, 0, 0, 0, 0); } return NULL; } /* * Print infos on file. * Return NPIC_SUCCESS, else error code. Verbose. */ int NpicNPZPrintInfo (const char *filename, Npic_npz_info *info) { int i; printf ("FILENAME \"%s\"\n", filename); if (info == NULL) return NPIC_ERR_NULL_PTR; printf ("MAGIC NPZ-%d\n", info->version); printf ("COMP %s\n", info->comp == NPIC_NPZ_GZIP ? "GZIP" : "NONE"); printf ("TYPE %s\n", NpicImageTypeName(info->type)); printf ("DIM %d\n", info->dim); printf ("XMAX %d\n", info->xmax); printf ("YMAX %d\n", info->ymax); if (info->dim >= 3) printf ("ZMAX %d\n", info->zmax); if (info->dim >= 4) printf ("TMAX %d\n", info->tmax); if (info->dim >= 5) printf ("SMAX %d\n", info->smax); if (info->dim >= 6) printf ("RMAX %d\n", info->rmax); for (i = 0; i < info->props.nb; i++) printf ("PROP %s: %s\n", info->props.list[i].key, info->props.list[i].val); return NPIC_SUCCESS; }