[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-cvs: CVS update: Makefile.am
User: cnieves
Date: 05/09/30 18:01:53
Modified: . Makefile.am o_picture.nw
Added: . s_encoding.nw
Log:
Added support for embedded pictures.
Revision Changes Path
1.9 +2 -2 eda/geda/devel/libgeda/noweb/Makefile.am
(In the diff below, changes in quantity of whitespace are not shown.)
Index: Makefile.am
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/noweb/Makefile.am,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- Makefile.am 19 Feb 2005 23:27:32 -0000 1.8
+++ Makefile.am 30 Sep 2005 22:01:52 -0000 1.9
@@ -5,7 +5,7 @@
o_complex_basic.nw o_image.nw o_line_basic.nw o_list.nw \
o_net_basic.nw o_pin_basic.nw o_selection.nw o_text_basic.nw \
s_attrib.nw s_basic.nw s_clib.nw s_color.nw s_conn.nw s_cue.nw \
- s_hierarchy.nw s_log.nw s_page.nw s_papersizes.nw \
+ s_encoding.nw s_hierarchy.nw s_log.nw s_page.nw s_papersizes.nw \
s_slib.nw s_stretch.nw s_tile.nw s_undo.nw s_menu.nw \
s_toplevel.nw u_basic.nw g_register.nw g_rc.nw i_vars.nw \
o_picture.nw gdk-pixbuf-hacks.nw
1.7 +109 -14 eda/geda/devel/libgeda/noweb/o_picture.nw
(In the diff below, changes in quantity of whitespace are not shown.)
Index: o_picture.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/noweb/o_picture.nw,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- o_picture.nw 20 Apr 2005 15:50:16 -0000 1.6
+++ o_picture.nw 30 Sep 2005 22:01:52 -0000 1.7
@@ -73,6 +73,7 @@
#ifndef HAS_GTK12
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
#endif
#include "defines.h"
@@ -151,11 +152,11 @@
if ( (embedded > 1) || (embedded < 0)) {
fprintf(stderr, "Found a picture with a wrong 'embedded' parameter: %c.\n",
- mirrored);
+ embedded);
s_log_message("Found a picture with a wrong 'embedded' parameter: %c.\n",
- mirrored);
- s_log_message("Setting mirrored to 0\n");
- mirrored = 0;
+ embedded);
+ s_log_message("Setting embedded to 0\n");
+ embedded = 0;
}
switch(angle) {
@@ -191,8 +192,51 @@
#endif
}
else {
- fprintf(stderr, "Embedded pictures are not supported yet.\n");
- s_log_message ("Embedded pictures are not supported yet.\n");
+ GString *encoded_picture=g_string_new("");
+ GdkPixdata pixdata;
+ guint pixdata_serialized_length;
+ gchar *pixdata_serialized_data;
+ char finished = 0;
+
+ /* Read the encoded picture */
+ do {
+ finished = 0;
+ fgets(buffer, 1024, fp);
+ if (g_strcasecmp(buffer, ".\n") != 0) {
+ encoded_picture=g_string_append (encoded_picture, buffer);
+ encoded_picture=g_string_append (encoded_picture, "\n");
+ }
+ else {
+ finished = 1;
+ }
+ } while (finished == 0);
+
+ /* Decode the picture */
+ pixdata_serialized_data=s_encoding_base64_decode(encoded_picture->str,
+ encoded_picture->len,
+ &pixdata_serialized_length);
+ if (pixdata_serialized_data == NULL) {
+ fprintf(stderr, "Error decoding picture.\n");
+ s_log_message ("Error decoding picture.\n");
+ }
+ else {
+ /* Deserialize the picture */
+ if (!gdk_pixdata_deserialize(&pixdata,pixdata_serialized_length,
+ (guint8 *) pixdata_serialized_data, NULL)) {
+ fprintf(stderr, "Error deserializing picture.\n");
+ }
+ else {
+ pixbuf = gdk_pixbuf_from_pixdata (&pixdata,TRUE, NULL);
+ }
+ }
+
+ if (pixdata_serialized_data != NULL) {
+ free (pixdata_serialized_data);
+ }
+ if (encoded_picture != NULL) {
+ g_string_free (encoded_picture, TRUE);
+ }
+
}
if (pixbuf == NULL) {
@@ -245,6 +289,11 @@
o_picture_save(OBJECT *object)
{
int width, height, x1, y1;
+ gchar *encoded_picture=NULL;
+ gchar *out=NULL;
+ gchar *pixdata_serialized_data=NULL;
+ guint pixdata_serialized_stream_length;
+ guint encoded_picture_length;
/* calculate the width and height of the box */
width = abs(object->picture->lower_x - object->picture->upper_x);
@@ -258,15 +307,60 @@
printf("picture: %d %d %d %d\n", x1, y1, width, height);
#endif
- return(g_strdup_printf("%c %d %d %d %d %d %c %c\n%s",
+ /* Encode the picture if it's embedded */
+ if (object->picture->embedded == 1) {
+ GdkPixdata pixdata;
+
+ /* Serialize the picture data */
+ gdk_pixdata_from_pixbuf (&pixdata, object->picture->original_picture, FALSE);
+ pixdata_serialized_data = (gchar *) gdk_pixdata_serialize(&pixdata,
+ &pixdata_serialized_stream_length);
+ if (pixdata_serialized_data == NULL) {
+ fprintf (stderr, "ERROR: o_picture_save: failed to create serialized data from picture\n");
+ s_log_message ("ERROR: o_picture_save: failed to create serialized data from picture\n");
+ }
+ else {
+ /* Encode the picture */
+ encoded_picture = s_encoding_base64_encode(pixdata_serialized_data,
+ pixdata_serialized_stream_length,
+ &encoded_picture_length, TRUE);
+ if (encoded_picture == NULL) {
+ fprintf(stderr, "ERROR: o_picture_save: unable to encode the picture.\n");
+ s_log_message("ERROR: o_picture_save: unable to encode the picture.\n");
+ }
+ }
+ }
+
+ if (object->picture->embedded==1) {
+ out = g_strdup_printf("%c %d %d %d %d %d %c %c\n%s\n%s\n%s",
object->type,
x1, y1, width, height,
object->picture->angle,
/* Convert the (0,1) chars to ASCII */
(object->picture->mirrored)+0x30,
- 0+0x30, /* No embedded pictures support yet */
- object->picture->filename));
+ object->picture->embedded+0x30,
+ object->picture->filename,
+ encoded_picture,
+ ".");
+ }
+ else {
+ out = g_strdup_printf("%c %d %d %d %d %d %c %c\n%s",
+ object->type,
+ x1, y1, width, height,
+ object->picture->angle,
+ /* Convert the (0,1) chars to ASCII */
+ (object->picture->mirrored)+0x30,
+ object->picture->embedded+0x30,
+ object->picture->filename);
+ }
+ if (encoded_picture != NULL) {
+ free(encoded_picture);
+ }
+ if (pixdata_serialized_data != NULL) {
+ free(pixdata_serialized_data);
+ }
+ return(out);
}
@@ -377,6 +471,7 @@
picture->displayed_picture = NULL;
picture->angle = angle;
picture->mirrored = mirrored;
+picture->embedded = embedded;
if (picture->original_picture == NULL) {
fprintf(stderr, "new picture: Couldn't get enough memory for the new picture\n");
1.1 eda/geda/devel/libgeda/noweb/s_encoding.nw
Index: s_encoding.nw
===================================================================
@c -*- mode: Noweb; noweb-doc-mode: texinfo-mode; noweb-code-mode: c-mode -*-
@node File s_encoding.c,,,Top
@chapter File @file{s_encoding.c}
@section File header
<<s_encoding.c : *>>=
<<s_encoding.c : copyright and license>>
/* Taken from gnet's sources */
/* Modified the name of the functions and some variables */
/* DO NOT read or edit this file ! Use ../noweb/s_encoding.nw instead */
<<s_encoding.c : include_directives>>
<<s_encoding.c : base64_encode()>>
<<s_encoding.c : base64_decode()>>
@
<<s_encoding.c : copyright and license>>=
/***********************************************************************
* _ _ __ _ _
* __ _ _ __ ___| |_ | |__ __ _ ___ ___ / /_ | || |
* / _` | '_ \ / _ \ __| | '_ \ / _` / __|/ _ \ '_ \| || |_
* | (_| | | | | __/ |_ | |_) | (_| \__ \ __/ (_) |__ _|
* \__, |_| |_|\___|\__| |_.__/ \__,_|___/\___|\___/ |_|
* |___/
*
* created by Alfred Reibenschuh <alfredreibenschuh@xxxxxxx>,
* under the ``GNU Library General Public License´´ (see below).
*
***********************************************************************
*
* Copyright (C) 2003 Free Software Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
***********************************************************************/
@
<<s_encoding.c : include_directives>>=
#include <ctype.h>
#include <glib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
@
@section Function @code{s_encoding_base64_encode()}
@defun s_encoding_base64_encode src srclen dstlenp strict
@end defun
<<s_encoding.c : base64_encode()>>=
static gchar s_encoding_Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define s_encoding_Pad64 '='
static guchar s_encoding_Base64_rank[256] = {
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0x00-0x0f */
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0x10-0x1f */
255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, /* 0x20-0x2f */
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,255,255,255, /* 0x30-0x3f */
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4f */
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, /* 0x50-0x5f */
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6f */
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, /* 0x70-0x7f */
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0x80-0x8f */
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0x90-0x9f */
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0xa0-0xaf */
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0xb0-0xbf */
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0xc0-0xcf */
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0xd0-0xdf */
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0xe0-0xef */
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 0xf0-0xff */
};
/**
* s_encoding_base64_encode
* @src: source buffer
* @srclen: length of the source buffer
* @dstlenp: length of the buffer returned (including the terminating \0)
* @strict: insert new lines as required by RFC 2045
*
* Convert a buffer from binary to base64 representation. Set
* @strict to TRUE to insert a newline every 72th character. This is
* required by RFC 2045, but some applications don't require this.
*
* Returns: caller-owned buffer.
*
**/
gchar*
s_encoding_base64_encode (gchar* src, guint srclen, guint* dstlenp, gboolean strict)
{
gchar* dst;
guint dstpos;
guchar input[3];
guchar output[4];
guint ocnt;
guint i;
if (srclen == 0)
return NULL; /* FIX: Or return ""? */
/* Calculate required length of dst. 4 bytes of dst are needed for
every 3 bytes of src. */
*dstlenp = (((srclen + 2) / 3) * 4)+5;
if (strict)
*dstlenp += (*dstlenp / 72); /* Handle trailing \n */
dst = g_new(gchar, *dstlenp );
/* bulk encoding */
dstpos = 0;
ocnt = 0;
while (srclen >= 3)
{
/*
Convert 3 bytes of src to 4 bytes of output
output[0] = input[0] 7:2
output[1] = input[0] 1:0 input[1] 7:4
output[2] = input[1] 3:0 input[2] 7:6
output[3] = input[1] 5:0
*/
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
srclen -= 3;
output[0] = (input[0] >> 2);
output[1] = ((input[0] & 0x03) @<< 4) + (input[1] @>> 4);
output[2] = ((input[1] & 0x0f) @<< 2) + (input[2] @>> 6);
output[3] = (input[2] & 0x3f);
g_assert ((dstpos + 4) < *dstlenp);
/* Map output to the Base64 alphabet */
dst[dstpos++] = s_encoding_Base64[(guint) output[0]];
dst[dstpos++] = s_encoding_Base64[(guint) output[1]];
dst[dstpos++] = s_encoding_Base64[(guint) output[2]];
dst[dstpos++] = s_encoding_Base64[(guint) output[3]];
/* Add a newline if strict and */
if (strict)
if ((++ocnt % (72/4)) == 0)
dst[dstpos++] = '\n';
}
/* Now worry about padding with remaining 1 or 2 bytes */
if (srclen != 0)
{
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclen; i++)
input[i] = *src++;
output[0] = (input[0] >> 2);
output[1] = ((input[0] & 0x03) @<< 4) + (input[1] @>> 4);
output[2] = ((input[1] & 0x0f) @<< 2) + (input[2] @>> 6);
g_assert ((dstpos + 4) < *dstlenp);
dst[dstpos++] = s_encoding_Base64[(guint) output[0]];
dst[dstpos++] = s_encoding_Base64[(guint) output[1]];
if (srclen == 1)
dst[dstpos++] = s_encoding_Pad64;
else
dst[dstpos++] = s_encoding_Base64[(guint) output[2]];
dst[dstpos++] = s_encoding_Pad64;
}
g_assert (dstpos <= *dstlenp);
dst[dstpos] = '\0';
*dstlenp = dstpos + 1;
return dst;
}
@ %def s_encoding_base64_encode
@defun s_encoding_base64_decode src srclen dstlenp
@end defun
<<s_encoding.c : base64_decode()>>=
/**
* s_encoding_base64_decode
* @src: the source buffer
* @srclen: the length of the source buffer
* @dstlenp: pointer to length of the destination buffer
*
* Convert a buffer from base64 to binary representation. This
* function is liberal in what it will accept. It ignores non-base64
* symbols.
*
* Returns: caller-owned buffer. The integer pointed to by @dstlenp
* is set to the length of that buffer.
*
**/
gchar*
s_encoding_base64_decode (gchar* src, guint srclen, guint* dstlenp)
{
gchar* dst;
guint dstidx, state, ch = 0;
gchar res;
guchar pos;
if (srclen == 0)
srclen = strlen(src);
state = 0;
dstidx = 0;
res = 0;
dst = g_new(gchar, srclen+1);
*dstlenp = srclen+1;
while (srclen-- > 0)
{
ch = *src++;
if (s_encoding_Base64_rank[ch]==255) /* Skip any non-base64 anywhere */
continue;
if (ch == s_encoding_Pad64)
break;
pos = s_encoding_Base64_rank[ch];
switch (state)
{
case 0:
if (dst != NULL)
{
dst[dstidx] = (pos << 2);
}
state = 1;
break;
case 1:
if (dst != NULL)
{
dst[dstidx] |= (pos >> 4);
res = ((pos & 0x0f) << 4);
}
dstidx++;
state = 2;
break;
case 2:
if (dst != NULL)
{
dst[dstidx] = res | (pos >> 2);
res = (pos & 0x03) << 6;
}
dstidx++;
state = 3;
break;
case 3:
if (dst != NULL)
{
dst[dstidx] = res | pos;
}
dstidx++;
state = 0;
break;
default:
break;
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == s_encoding_Pad64) /* We got a pad char. */
{
switch (state)
{
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return NULL;
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
while (srclen-- > 0)
{
ch = *src++;
if (s_encoding_Base64_rank[ch] != 255) break;
}
/* Make sure there is another trailing = sign. */
if (ch != s_encoding_Pad64)
{
g_free(dst);
*dstlenp = 0;
return NULL;
}
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
while (srclen-- > 0)
{
ch = *src++;
if (s_encoding_Base64_rank[ch] != 255)
{
g_free(dst);
*dstlenp = 0;
return NULL;
}
}
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (dst != NULL && res != 0)
{
g_free(dst);
*dstlenp = 0;
return NULL;
}
default:
break;
}
} else
{
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
{
g_free(dst);
*dstlenp = 0;
return NULL;
}
}
dst[dstidx]=0;
*dstlenp = dstidx;
return dst;
}
@ %def s_encoding_base64_decode