// -*- C++ -*- // Copyright 2006-2007 Deutsches Forschungszentrum fuer Kuenstliche Intelligenz // or its licensors, as applicable. // // You may not use this file except under the terms of the accompanying license. // // 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. // // Project: ocr-utils // File: narray-io.h // Purpose: I/O utilities // Responsible: mezhirov // Reviewer: // Primary Repository: // Web Sites: www.iupr.org, www.dfki.de /// \file narray-io.h /// \brief I/O utilities for narrays #ifndef h_narray_io_ #define h_narray_io_ #include #include #include "colib.h" namespace ocropus { // ____________________ printing narrays for humans _______________________ /// Print a 2D array formatted with to the given format string. template void printf_matrix(const char *format, colib::narray &a) { ASSERT(a.rank() == 2); for(int i = 0; i < a.dim(0); i++) { for(int j = 0; j < a.dim(1); j++) { if(j) putchar(' '); printf(format, a(i,j)); } putchar('\n'); } } /// Print any array as 1D vector formatted with the given format string. template void printf_vector(const char *format, colib::narray &a) { for(int i = 0; i < a.length1d(); i++) { if(i) putchar(' '); printf(format, a.at1d(i)); } putchar('\n'); } /// Print any 1D or 2D array formatted with the given format string. template void printf_narray(const char *format, colib::narray &a) { if(a.rank() == 2) printf_matrix(format, a); else printf_vector(format, a); } /// Print a 1D or 2D doublearray to stdout. inline void print(colib::doublearray &a) {printf_narray("%g", a);} /// Print a 1D or 2D floatarray to stdout. inline void print(colib::floatarray &a) {printf_narray("%g", a);} /// Print a 1D or 2D intarray to stdout. inline void print(colib::intarray &a) {printf_narray("%d", a);} // ________________________ text I/O for narrays _______________________ /// Write a 1D intarray in a simple format: length and items. void text_write_1d(FILE *, colib::intarray &); /// Read a 1D intarray in a simple format: length and items. void text_read_1d(FILE *, colib::intarray &); // FIXME rename these to write_narray_text (verb first!) //\{ /// Write the array (with dimensions) into a text file. void text_write(FILE *, colib::floatarray &); inline void text_write(colib::floatarray &a, FILE *f) {text_write(f, a);} void text_write(FILE *, colib::doublearray &); inline void text_write(colib::doublearray &a, FILE *f) {text_write(f, a);} void text_write(FILE *, colib::intarray &); inline void text_write(colib::intarray &a, FILE *f) {text_write(f, a);} void text_write(FILE *, colib::bytearray &); inline void text_write(colib::bytearray &a, FILE *f) {text_write(f, a);} //\} //\{ /// Read the array (with dimensions) from a text file. void text_read(FILE *, colib::floatarray &); inline void text_read(colib::floatarray &a, FILE *f) {text_read(f, a);} void text_read(FILE *, colib::doublearray &); inline void text_read(colib::doublearray &a, FILE *f) {text_read(f, a);} void text_read(FILE *, colib::intarray &); inline void text_read(colib::intarray &a, FILE *f) {text_read(f, a);} void text_read(FILE *, colib::bytearray &); inline void text_read(colib::bytearray &a, FILE *f) {text_read(f, a);} //\} // ______________________ binary I/O for primitives _______________________ //\{ /// Write a 32-bit integer into the file in a binary form, MSB first. inline void write_int32(int32_t n, FILE *f) { fputc(n >> 24, f); fputc(n >> 16, f); fputc(n >> 8, f); fputc(n, f); } inline void write_int32(FILE *f, int32_t n) {write_int32(n,f);} //\} /// \brief Read a 32-bit integer from the file in a binary form, MSB first. /// Doesn't check for EOF. inline int32_t read_int32(FILE *f) { int i = fgetc(f); i = (i << 8) | fgetc(f); i = (i << 8) | fgetc(f); i = (i << 8) | fgetc(f); return i; } //\{ /// Read a rectangle in a binary format. inline void bin_read(FILE *f, colib::rectangle &r) { r.x0 = read_int32(f); r.y0 = read_int32(f); r.x1 = read_int32(f); r.y1 = read_int32(f); } inline void bin_read(colib::rectangle &r, FILE *f) {bin_read(f,r);} //\} //\{ /// Write a rectangle in a binary format. inline void bin_write(FILE *f, colib::rectangle &r) { write_int32(f, r.x0); write_int32(f, r.y0); write_int32(f, r.x1); write_int32(f, r.y1); } inline void bin_write(colib::rectangle &r, FILE *f) {bin_write(f,r);} //\} //\{ /// \brief Read a bytearray as fread() does. /// The number of bytes is determined by the array length. inline int read_raw(FILE *f, colib::bytearray &a) { return fread(a.data, 1, a.length1d(), f); } inline int read_raw(colib::bytearray &a, FILE *f) {return read_raw(f, a);} //\} //\{ /// \brief Write a bytearray as fwrite() does. inline int write_raw(FILE *f, colib::bytearray &a) { return fwrite(a.data, 1, a.length1d(), f); } inline int write_raw(colib::bytearray &a, FILE *f) {return write_raw(f, a);} //\} // ______________________________ misc ____________________________________ /// Create a 1D doublearray given a string with space-separated numbers. void parse_vector(colib::doublearray &,const char *); /// Create a 1D intarray given a string with space-separated numbers. inline void parse_vector(colib::intarray &result, const char *s) { colib::doublearray tmp; parse_vector(tmp, s); colib::copy(result, tmp); } // FIXME rename these to write_narray_bin etc. void bin_write_1d(FILE *, colib::intarray &); void bin_read_1d(FILE *, colib::intarray &); void bin_write_mnist_dims(FILE *, colib::intarray &); void bin_read_mnist_dims(FILE *, colib::intarray &); void bin_write(FILE *, colib::bytearray &); inline void bin_write(colib::bytearray &a, FILE *f) {bin_write(f, a);} void bin_read(FILE *, colib::bytearray &); inline void bin_read(colib::bytearray &a, FILE *f) {bin_read(f, a);} void bin_append(FILE *, colib::bytearray &); inline void bin_append(colib::bytearray &a, FILE *f) {bin_append(f, a);} inline void bin_read(const char *path, colib::bytearray &a) { bin_read(colib::stdio(path, "rb"), a); } inline void bin_read(colib::bytearray &a, const char *path) { bin_read(path, a); } inline void bin_write(const char *path, colib::bytearray &a) { bin_write(colib::stdio(path, "wb"), a); } inline void bin_write(colib::bytearray &a, const char *path) { bin_write(path, a); } inline void bin_append(const char *path, colib::bytearray &a) { FILE *test = fopen(path, "rb"); fclose(test); if(test) { colib::stdio f(path, "r+b"); bin_append(f, a); } else { colib::stdio f(path, "wb"); bin_write(f, a); } } inline void bin_append(colib::bytearray &a, const char *path) { bin_append(path, a); } void bin_write_nustring(FILE *f, colib::nustring &a); void bin_read_nustring(FILE *f, colib::nustring &a); /// Read a line from the file, allocating memory with malloc(). char *read_line_malloc(FILE *f); /// Write utf8-encoded string followed by a newline. void write_utf8(FILE *f, colib::nustring &a); /// Read a line and decode it from utf-8. bool read_utf8_line(colib::nustring &a, FILE *f); bool read_utf8(colib::nustring &a, FILE *f) WARN_DEPRECATED; /// \brief Write a `checkpoint' to the file. /// A checkpoint is just some text lying around for 4 purposes: /// - after fscanf() it's unwise to use binary I/O, /// but after a checkpoint it's OK; /// - a checkpoint makes it easier to find stuff in the saved file /// - extra check when loading /// - versioning info can be stored in a checkpoint void write_checkpoint(FILE *f, const char *); /// \brief Read a `checkpoint'. /// The given identifier should exactly match the one in the file. void read_checkpoint(FILE *f, const char *); }; #endif