Re: [Gegl-developer] npy saving operation



Ok. I'll use GString instead, as I need both the length of the resulting string as well as the string, and thus can't use fprintf (unless I fseek backwards).

Thanks,
Dov


On Wed, May 29, 2013 at 12:53 AM, Michael Henning <drawoc darkrefraction com> wrote:
Using sprintf like that opens you up to to buffer overflows. Could you
switch that part of the code to use fprintf directly on the file
pointer? It would also simplify the code.

Otherwise, I have nothing against committing this.

On Tue, May 28, 2013 at 5:27 PM, Dov Grobgeld <dov grobgeld gmail com> wrote:
> I finished a saver operation for floating point npy images. It may e.g. be
> used to debug floating point operations (e.g. gaussian-blur) with numerical
> python. The resulting image may be read into numpy as follows:
>
>    import numpy
>    img = numpy.load('image.npy')
>
> It may also be viewed in my image viewer giv (though it currently does not
> support color npy images).
>
> Is it ok to commit it?
>
> Follows the code.
>
> Regards,
> Dov
>
> /* This file is an image processing operation for GEGL
>  *
>  * GEGL is free software; you can redistribute it and/or
>  * modify it under the terms of the GNU Lesser General Public
>  * License as published by the Free Software Foundation; either
>  * version 3 of the License, or (at your option) any later version.
>  *
>  * GEGL 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
>  * Lesser General Public License for more details.
>  *
>  * You should have received a copy of the GNU Lesser General Public
>  * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
>  *
>  * Copyright Dov Grobgeld 2013 <dov.grobgeld (a) gmail.com>
>  *
>  * This operation saves a buffer in the npy file format. It may be
>  * read into python as follows:
>  *
>  *   import numpy
>  *   img = numpy.load('image.npy')
>  */
>
> #include "config.h"
> #include <glib/gi18n-lib.h>
>
>
> #ifdef GEGL_CHANT_PROPERTIES
>
> gegl_chant_string  (path, _("File"), "",
>                     _("Target path and filename, use '-' for stdout."))
>
> #else
>
> #define GEGL_CHANT_TYPE_SINK
> #define GEGL_CHANT_C_FILE       "npy-save.c"
>
> #include "gegl-chant.h"
> #include <stdio.h>
>
> static int npywrite(FILE *fp, guchar *data, int width, int height, int
> num_channels)
> {
>     char header[100];
>     unsigned short header_len;
>
>     // Write header and version number to file
>     fwrite("\223NUMPY"
>            "\001\000"
>            , 1, 8, fp);
>     if (num_channels == 3)
>       sprintf(header,
>               "{'descr': '<f4', 'fortran_order': False, 'shape': (%d, %d,
> 3), } \n",
>               height, width);
>     else
>       sprintf(header,
>               "{'descr': '<f4', 'fortran_order': False, 'shape': (%d, %d), }
> \n",
>               height, width);
>
>     header_len = strlen(header);
>     fwrite(&header_len, 2, 1, fp);
>     fwrite(header, header_len, 1, fp);
>
>     fwrite(data, width*height*num_channels, sizeof(float), fp);
>
>     return 0;
> }
>
> static gboolean
> process (GeglOperation       *operation,
>          GeglBuffer          *input,
>          const GeglRectangle *rect,
>          gint                 level)
> {
>   GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
>
>   FILE     *fp;
>   guchar   *data;
>   gsize     bpc;
>   gsize     numsamples;
>   gsize     numchannels;
>   gboolean  ret = FALSE;
>   const Babl *output_format;
>   const Babl *input_format = gegl_buffer_get_format(input);
>
>   // Get the current format and use it to decide whether to save
>   // the output in color or gray level formats.
>   bpc = sizeof(gfloat);
>   if (babl_format_get_n_components(input_format) >= 3)
>     {
>       numchannels = 3;
>       output_format = babl_format("RGB float");
>     }
>   else
>     {
>       numchannels = 1;
>       output_format = babl_format ("Y float");
>     }
>
>   numsamples = rect->width * rect->height * numchannels;
>
>   data = "" (numsamples * bpc);
>   gegl_buffer_get (input, rect, 1.0, output_format, data,
>                    GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
>
>   fp = (!strcmp (o->path, "-") ? stdout : fopen(o->path, "wb") );
>
>   npywrite(fp, data, rect->width, rect->height, numchannels);
>
>   g_free (data);
>
>   return ret;
> }
>
> static void
> gegl_chant_class_init (GeglChantClass *klass)
> {
>   GeglOperationClass     *operation_class;
>   GeglOperationSinkClass *sink_class;
>
>   operation_class = GEGL_OPERATION_CLASS (klass);
>   sink_class      = GEGL_OPERATION_SINK_CLASS (klass);
>
>   sink_class->process = process;
>   sink_class->needs_full = TRUE;
>
>   gegl_operation_class_set_keys (operation_class,
>     "name"        , "gegl:npy-save",
>     "categories"  , "output",
>     "description" ,
>         _("NPY image saver (Numerical python file saver.)"),
>         NULL);
>
>   gegl_extension_handler_register_saver (".npy", "gegl:npy-save");
> }
>
> #endif
>
>
> _______________________________________________
> gegl-developer-list mailing list
> gegl-developer-list gnome org
> https://mail.gnome.org/mailman/listinfo/gegl-developer-list
>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]