last-svn-commit-766-gb14b7ee Add Base64 conversion routines.

* scribo/scribo/convert/from_base64.hh, * scribo/scribo/convert/to_base64.hh: New routines. * scribo/tests/Makefile.am, * scribo/tests/convert/Makefile.am, * scribo/tests/convert/base64.cc: New associated test. --- scribo/ChangeLog | 11 ++ scribo/scribo/convert/from_base64.hh | 217 ++++++++++++++++++++++++++++ scribo/scribo/convert/to_base64.hh | 185 ++++++++++++++++++++++++ scribo/tests/Makefile.am | 1 + scribo/tests/{core => convert}/Makefile.am | 8 +- scribo/tests/convert/base64.cc | 89 ++++++++++++ 6 files changed, 507 insertions(+), 4 deletions(-) create mode 100644 scribo/scribo/convert/from_base64.hh create mode 100644 scribo/scribo/convert/to_base64.hh copy scribo/tests/{core => convert}/Makefile.am (84%) create mode 100644 scribo/tests/convert/base64.cc diff --git a/scribo/ChangeLog b/scribo/ChangeLog index 1bd708a..7b409a2 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,3 +1,14 @@ +2011-02-17 Guillaume Lazzara <z@lrde.epita.fr> + + Add Base64 conversion routines. + + * scribo/scribo/convert/from_base64.hh, + * scribo/scribo/convert/to_base64.hh: New routines. + + * scribo/tests/Makefile.am, + * scribo/tests/convert/Makefile.am, + * scribo/tests/convert/base64.cc: New associated test. + 2011-02-05 Guillaume Lazzara <z@lrde.epita.fr> Add support for whitespace separators visualization. diff --git a/scribo/scribo/convert/from_base64.hh b/scribo/scribo/convert/from_base64.hh new file mode 100644 index 0000000..8c14a0f --- /dev/null +++ b/scribo/scribo/convert/from_base64.hh @@ -0,0 +1,217 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + + + +#ifndef SCRIBO_CONVERT_FROM_BASE64_HH +# define SCRIBO_CONVERT_FROM_BASE64_HH + +/*! \file + + \brief Decode base64 raw data and convert it to an image. + + Based on Bob Trower's code. + http://base64.sourceforge.net/b64.c + + LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall + be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS + OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <cstdio> +#include <cstdlib> + +# include <mln/border/resize.hh> +# include <mln/core/image/image2d.hh> +# include <mln/util/array.hh> + + + +namespace scribo +{ + + namespace convert + { + + using namespace mln; + + template <typename I> + void from_base64(const util::array<unsigned char>& data64, + Image<I>& output); + + +# if defined HAVE_QT + + template <typename I> + void from_base64(const QString& data64, Image<I>& output_); + +# endif // ! HAVE_QT + + +# ifndef MLN_INCLUDE_ONLY + + + namespace internal + { + + /* + ** Translation Table to decode + */ + static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; + + /* + ** decodeblock + ** + ** decode 4 '6-bit' characters into 3 8-bit binary bytes + */ + inline + void + decodeblock(unsigned char in[4], unsigned char out[3]) + { + out[ 0 ] = (unsigned char) (in[0] << 2 | in[1] >> 4); + out[ 1 ] = (unsigned char) (in[1] << 4 | in[2] >> 2); + out[ 2 ] = (unsigned char) (((in[2] << 6) & 0xc0) | in[3]); + } + + + template <typename V, typename I> + void + from_base64_(const V& data64, const unsigned length, Image<I>& output_) + { + trace::entering("scribo::convert::from_base64_"); + + mln_precondition(exact(output_).is_valid()); + using namespace internal; + + I& output = exact(output_); + + unsigned char in[4], out[3], v; + int i, len; + + border::resize(output, 0); // Make sure there is no border! + + unsigned char *ptr = (unsigned char *)output.buffer(); + unsigned char *end_ptr = (unsigned char *)(output.buffer() + output.nelements()); + + for (unsigned idx = 0; idx < length;) + { + for(len = 0, i = 0; i < 4 && idx < length; i++) + { + v = 0; + while(idx < length && v == 0) + { + v = (unsigned char) data64[idx++]; + v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]); + if(v) + { + v = (unsigned char) ((v == '$') ? 0 : v - 61); + } + } + if(idx < length) + { + len++; + if(v) + { + in[ i ] = (unsigned char) (v - 1); + } + } + else + { + in[i] = 0; + } + } + if(len) + { + decodeblock(in, out); + for(i = 0; i < len - 1 && ptr != end_ptr; i++) + { + *ptr++ = out[i]; + } + } + } + + trace::exiting("scribo::convert::to_base64_"); + } + + + } // end of namespace scribo::convert::internal + + + template <typename I> + void + from_base64(const util::array<unsigned char>& data64, Image<I>& output_) + { + trace::entering("scribo::convert::from_base64"); + + internal::from_base64_(data64, data64.nelements(), output_); + + trace::exiting("scribo::convert::to_base64"); + } + + +# if defined HAVE_QT + + template <typename I> + void + from_base64(const QString& data64, Image<I>& output_) + { + trace::entering("scribo::convert::from_base64"); + + QByteArray data64_ = data64.toAscii(); + internal::from_base64_(data64_.constData(), data64_.size(), output_); + + trace::exiting("scribo::convert::to_base64"); + } + +# endif // ! HAVE_QT + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::convert + +} // end of namespace scribo + +#endif // ! SCRIBO_CONVERT_FROM_BASE64_HH diff --git a/scribo/scribo/convert/to_base64.hh b/scribo/scribo/convert/to_base64.hh new file mode 100644 index 0000000..8df3ed2 --- /dev/null +++ b/scribo/scribo/convert/to_base64.hh @@ -0,0 +1,185 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + + + +#ifndef SCRIBO_CONVERT_TO_BASE64_HH +# define SCRIBO_CONVERT_TO_BASE64_HH + +/*! \file + + \brief Encode an image into base64 raw data. + + Based on Bob Trower's code. + http://base64.sourceforge.net/b64.c + + LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall + be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS + OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +# include <cstdio> +# include <cstdlib> + +# include <mln/border/resize.hh> +# include <mln/core/image/image2d.hh> +# include <mln/util/array.hh> + + +# define B64_DEF_LINE_SIZE 72 + +namespace scribo +{ + + namespace convert + { + + using namespace mln; + + + template <typename I> + void + to_base64(const Image<I>& input, util::array<unsigned char>& output); + + +# ifndef MLN_INCLUDE_ONLY + + + namespace internal + { + + /* + ** Translation Table as described in RFC1113 + */ + static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + /* + ** encodeblock + ** + ** encode 3 8-bit binary bytes as 4 '6-bit' characters + */ + inline + void + encodeblock(unsigned char in[3], unsigned char out[4], int len) + { + out[0] = cb64[ in[0] >> 2 ]; + out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; + out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); + out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '='); + } + + } // end of namespace scribo::convert::internal + + + + template <typename I> + void + to_base64(const Image<I>& input_, util::array<unsigned char>& output) + { + trace::entering("scribo::convert::to_base64"); + + mln_precondition(exact(input_).is_valid()); + using namespace internal; + + const I& input = exact(input_); + + unsigned char in[3], out[4]; + int i, len, blocksout = 0; + + // FIXME: Take border into account while moving pointer and + // remove that call. + border::resize(input, 0); + + const unsigned char + *end_ptr = (unsigned char *) (input.buffer() + input.nelements()), + *ptr = (unsigned char *)input.buffer(); + + while(ptr != end_ptr) + { + len = 0; + for(i = 0; i < 3; ++i) + { + if (ptr != end_ptr) + { + in[i] = (unsigned char) *ptr++; + ++len; + } + else + { + in[i] = 0; + for(++i; i < 3; ++i) + in[i] = 0; + } + } + if(len) + { + encodeblock(in, out, len); + for(i = 0; i < 4; ++i) + output.append(out[i]); + ++blocksout; + } + if(blocksout >= (B64_DEF_LINE_SIZE/4) || ptr == end_ptr) + { + if(blocksout) + { + output.append('\r'); + output.append('\n'); + } + blocksout = 0; + } + } + + trace::exiting("scribo::convert::to_base64"); + } + +# endif // ! MLN_INCLUDE_ONLY + +# undef B64_DEF_LINE_SIZE + + } // end of namespace scribo::convert + +} // end of namespace scribo + +#endif // ! SCRIBO_CONVERT_TO_BASE64_HH diff --git a/scribo/tests/Makefile.am b/scribo/tests/Makefile.am index 1cb222b..09768b1 100644 --- a/scribo/tests/Makefile.am +++ b/scribo/tests/Makefile.am @@ -29,6 +29,7 @@ EXTRA_DIST = \ SUBDIRS = \ binarization \ + convert \ core \ filter \ preprocessing \ diff --git a/scribo/tests/core/Makefile.am b/scribo/tests/convert/Makefile.am similarity index 84% copy from scribo/tests/core/Makefile.am copy to scribo/tests/convert/Makefile.am index 356cc31..c4c912c 100644 --- a/scribo/tests/core/Makefile.am +++ b/scribo/tests/convert/Makefile.am @@ -1,5 +1,4 @@ -# Copyright (C) 2009, 2010 EPITA Research and Development Laboratory -# (LRDE). +# Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE). # # This file is part of Olena. # @@ -20,8 +19,9 @@ include $(top_srcdir)/scribo/tests/tests.mk -check_PROGRAMS = line_info +check_PROGRAMS = \ + base64 -line_info_SOURCES = line_info.cc +base64_SOURCES = base64.cc TESTS = $(check_PROGRAMS) diff --git a/scribo/tests/convert/base64.cc b/scribo/tests/convert/base64.cc new file mode 100644 index 0000000..18d08d9 --- /dev/null +++ b/scribo/tests/convert/base64.cc @@ -0,0 +1,89 @@ +// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE). +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. + +/// \file + +#include <cstdio> +#include <cstdlib> + +#include <mln/core/image/image2d.hh> +#include <mln/data/compare.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/load.hh> + +#include <mln/value/int_u.hh> +#include <mln/value/int_u8.hh> + +#include <mln/debug/iota.hh> + +#include <mln/value/int_u16.hh> + +#include <scribo/convert/to_base64.hh> +#include <scribo/convert/from_base64.hh> + +#include "tests/data.hh" + +using namespace mln; + +int main() +{ + + // PBM + { + image2d<bool> ima; + io::pbm::load(ima, SCRIBO_IMG_DIR "/wildly.pbm"); + + util::array<unsigned char> out64; + scribo::convert::to_base64(ima, out64); + + image2d<bool> outbin(ima.domain()); + scribo::convert::from_base64(out64, outbin); + + mln_assertion(outbin == ima); + } + + // PGM (8bits) + { + image2d<value::int_u8> ima; + io::pgm::load(ima, SCRIBO_IMG_DIR "/text_to_group.pgm"); + + util::array<unsigned char> out64; + scribo::convert::to_base64(ima, out64); + + image2d<value::int_u8> outbin(ima.domain()); + scribo::convert::from_base64(out64, outbin); + + mln_assertion(outbin == ima); + } + + // PGM (30bits) + { + image2d<value::int_u<30> > ima(3, 3); + debug::iota(ima, 100000); + + util::array<unsigned char> out64; + scribo::convert::to_base64(ima, out64); + + image2d<value::int_u<30> > outbin(ima.domain()); + scribo::convert::from_base64(out64, outbin); + + mln_assertion(outbin == ima); + } + + + return 0; +} -- 1.5.6.5
participants (1)
-
Guillaume Lazzara