Author: rpmcruz
Date: Fri Oct 12 14:35:29 2007
New Revision: 41406
URL: http://svn.opensuse.org/viewcvs/yast?rev=41406&view=rev
Log:
* src/ygdkmngloader.h/c / src/YGImage.cc: added support for inline MNG
images. Fixed ticks per second.
* tests/YGImage.ycp: added a bunch of MNGs I found...
Modified:
trunk/gtk/ChangeLog
trunk/gtk/src/YGImage.cc
trunk/gtk/src/ygdkmngloader.c
trunk/gtk/src/ygdkmngloader.h
trunk/gtk/tests/Image.ycp
trunk/gtk/tests/ImageMng.ycp
Modified: trunk/gtk/ChangeLog
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/ChangeLog?rev=41406&r1=41405&r2=41406&view=diff
==============================================================================
--- trunk/gtk/ChangeLog (original)
+++ trunk/gtk/ChangeLog Fri Oct 12 14:35:29 2007
@@ -1,3 +1,9 @@
+2007-10-12 Ricardo Cruz
+
+ * src/ygdkmngloader.h/c / src/YGImage.cc: added support for inline MNG
+ images.
+ * tests/YGImage.ycp: added a bunch of MNGs I found...
+
2007-10-11 Ricardo Cruz
* src/YGPackageSelector.cc: speed up Patterns view.
Modified: trunk/gtk/src/YGImage.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGImage.cc?rev=41406&r1=41405&r2=41406&view=diff
==============================================================================
--- trunk/gtk/src/YGImage.cc (original)
+++ trunk/gtk/src/YGImage.cc Fri Oct 12 14:35:29 2007
@@ -125,15 +125,24 @@
alt_text = g_strdup (text->value_cstr());
initOptions (opt);
- GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
- g_signal_connect (G_OBJECT (loader), "area-prepared",
- G_CALLBACK (image_loaded_cb), this);
-
GError *error = 0;
- if (!gdk_pixbuf_loader_write (loader,
- byteblock->value(), byteblock->size(), &error))
- g_warning ("Could not load image from data blocks: %s", error->message);
- gdk_pixbuf_loader_close (loader, &error);
+ if (m_isAnimation && ygdk_mng_pixbuf_is_data_mng (byteblock->value(), byteblock->size()))
+ {
+ GdkPixbufAnimation *pixbuf;
+ pixbuf = ygdk_mng_pixbuf_new_from_data (byteblock->value(), byteblock->size(), &error);
+ loadAnimation (pixbuf, error ? error->message : "(undefined)");
+ }
+ else
+ {
+ GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
+ g_signal_connect (G_OBJECT (loader), "area-prepared",
+ G_CALLBACK (image_loaded_cb), this);
+
+ if (!gdk_pixbuf_loader_write (loader,
+ byteblock->value(), byteblock->size(), &error))
+ g_warning ("Could not load image from data blocks: %s", error->message);
+ gdk_pixbuf_loader_close (loader, &error);
+ }
}
virtual ~YGImage()
Modified: trunk/gtk/src/ygdkmngloader.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygdkmngloader.c?rev=41406&r1=41405&r2=41406&view=diff
==============================================================================
--- trunk/gtk/src/ygdkmngloader.c (original)
+++ trunk/gtk/src/ygdkmngloader.c Fri Oct 12 14:35:29 2007
@@ -30,47 +30,58 @@
//** Utilities to read the MNG file
-typedef gboolean (*ChunkParser)(YGdkMngPixbuf*, guint8*, GError**);
-
-struct ChunkLoad {
- guint8 Id;
- ChunkParser Function;
-
-};
+typedef struct DataStream {
+ const guint8 *data;
+ const long size;
+ long offset;
+} DataStream;
+static DataStream data_stream_constructor (const guint8 *raw_data, long size)
+{
+ DataStream data = { raw_data, size, 0 };
+ return data;
+}
-static gboolean read_signature (FILE *file)
+static gboolean read_signature (DataStream *data)
{
- guchar buf[8];
- fread (buf, 1, 8, file);
- return memcmp (buf, "\212MNG\r\n\032\n", 8) == 0;
+ if (data->offset+8 > data->size)
+ return FALSE;
+ data->offset += 8;
+ return memcmp (data->data + data->offset-8, "\212MNG\r\n\032\n", 8) == 0;
}
-static gboolean read_uint8 (FILE *file, guint8 *value)
+static gboolean read_uint8 (DataStream *data, guint8 *value)
{
- return fread (value, 1, 1, file) >= 1;
+ if (data->offset+1 > data->size)
+ return FALSE;
+ *value = data->data [data->offset++];
+ return TRUE;
}
-static gboolean read_uint32 (FILE *file, guint32 *value)
+static gboolean read_uint32 (DataStream *data, guint32 *value)
{
- guint8 buffer[4];
- if (fread (buffer, 1, 4, file) < 4)
+ if (data->offset+4 > data->size)
return FALSE;
- *value = buffer[0] << 24; *value |= buffer[1] << 16;
- *value |= buffer[2] << 8; *value |= buffer[3];
+ *value = data->data[data->offset+0] << 24;
+ *value |= data->data[data->offset+1] << 16;
+ *value |= data->data[data->offset+2] << 8;
+ *value |= data->data[data->offset+3];
+ data->offset += 4;
return TRUE;
}
-static gboolean read_data (FILE *file, guint32 size, GdkPixbufLoader *loader,
+static gboolean read_data (DataStream *data, guint32 size, GdkPixbufLoader *loader,
GError **error)
{
- guchar data [size];
- if (fread (data, 1, size, file) < size)
+ if (data->offset+size > data->size)
{
g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
"Unexpected end of file when reading PNG chunk");
return FALSE;
}
- return gdk_pixbuf_loader_write (loader, data, size, error);
+ gboolean ret;
+ ret = gdk_pixbuf_loader_write (loader, data->data + data->offset, size, error);
+ data->offset += size;
+ return ret;
}
static void image_prepared_cb (GdkPixbufLoader *loader, YGdkMngPixbuf *mng_pixbuf)
@@ -91,17 +102,34 @@
{
FILE *file = fopen (filename, "rb");
if (!file)
- return FALSE;
- return read_signature (file);
+ goto is_file_mng_failed;
+
+ guchar raw_data [8];
+ if (fread (raw_data, 1, 8, file) < 8)
+ goto is_file_mng_failed;
+
+ gboolean ret = ygdk_mng_pixbuf_is_data_mng (raw_data, 8);
+ fclose (file);
+ return ret;
+
+is_file_mng_failed:
+ fclose (file);
+ return FALSE;
+}
+
+gboolean ygdk_mng_pixbuf_is_data_mng (const guint8 *raw_data, long size)
+{
+ DataStream data = data_stream_constructor (raw_data, size);
+ return read_signature (&data);
}
+#define SET_ERROR(msg) { error = TRUE; \
+ g_set_error (error_msg, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, msg); }
+
GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_file (const gchar *filename,
GError **error_msg)
{
gboolean error = FALSE;
- #define SET_ERROR(msg) { error = TRUE; \
- g_set_error (error_msg, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, msg); }
-
FILE *file = fopen (filename, "rb");
if (!file)
{
@@ -109,7 +137,31 @@
return NULL;
}
- if (!read_signature (file))
+ fseek (file, 0, SEEK_END);
+ long file_size = ftell (file);
+ fseek (file, 0, SEEK_SET);
+
+ GdkPixbufAnimation *mng_pixbuf = 0;
+ guchar *data = mmap (NULL, file_size, PROT_READ, MAP_PRIVATE,
+ fileno (file), 0);
+ if (data == MAP_FAILED)
+ SET_ERROR ("Could not map file")
+ else
+ {
+ mng_pixbuf = ygdk_mng_pixbuf_new_from_data (data, file_size, error_msg);
+ munmap (data, file_size);
+ }
+ fclose (file);
+ return mng_pixbuf;
+}
+
+GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_data (const guint8 *raw_data, long size,
+ GError **error_msg)
+{
+ DataStream data = data_stream_constructor (raw_data, size);
+
+ gboolean error = FALSE;
+ if (!read_signature (&data))
{
SET_ERROR ("Not a MNG file")
return NULL;
@@ -119,19 +171,19 @@
mng_pixbuf->iteration_max = 0x7fffffff;
guint32 chunk_size, chunk_id;
- long offset;
+ long chunk_offset;
GdkPixbufLoader *loader = NULL; /* currently loading... */
gboolean first_read = TRUE;
do {
- error = !read_uint32 (file, &chunk_size);
- error = error || !read_uint32 (file, &chunk_id);
+ error = !read_uint32 (&data, &chunk_size);
+ error = error || !read_uint32 (&data, &chunk_id);
if (error)
{
SET_ERROR ("Unexpected end of file on new chunk")
break;
}
- offset = ftell (file) + chunk_size + 4/*CRC*/;
+ chunk_offset = data.offset + chunk_size + 4/*CRC*/;
if (first_read && chunk_id != MNG_UINT_MHDR)
{
@@ -154,9 +206,9 @@
if (chunk_size == 7*4)
{
// Read MHDR chunk data
- error = !read_uint32 (file, &mng_pixbuf->frame_width);
- error = error || !read_uint32 (file, &mng_pixbuf->frame_height);
- error = error || !read_uint32 (file, &mng_pixbuf->ticks_per_second);
+ error = !read_uint32 (&data, &mng_pixbuf->frame_width);
+ error = error || !read_uint32 (&data, &mng_pixbuf->frame_height);
+ error = error || !read_uint32 (&data, &mng_pixbuf->ticks_per_second);
if (error)
SET_ERROR ("Unexpected end of file on MHDR chunk")
/* Next atttributes: Nominal_layer_count, Nominal_frame_count,
@@ -165,7 +217,7 @@
mng_pixbuf->frame_height <= 0 ||
mng_pixbuf->ticks_per_second < 0)
SET_ERROR ("Invalid MHDR parameter")
-fprintf(stderr, "ticks per second: %d\n", mng_pixbuf->ticks_per_second);
+//fprintf(stderr, "ticks per second: %d\n", mng_pixbuf->ticks_per_second);
}
else
SET_ERROR ("MHDR chunk must be 28 bytes long")
@@ -191,12 +243,12 @@
{
// Read TERM chunk data
guint8 t;
- error = !read_uint8 (file, &t); // term action
+ error = !read_uint8 (&data, &t); // term action
if (t == 3 && chunk_size == 2+8)
{
- error = error || !read_uint8 (file, &t); // after term action
- error = error || !read_uint32 (file, &mng_pixbuf->last_frame_delay);
- error = error || !read_uint32 (file, &mng_pixbuf->iteration_max);
+ error = error || !read_uint8 (&data, &t); // after term action
+ error = error || !read_uint32 (&data, &mng_pixbuf->last_frame_delay);
+ error = error || !read_uint32 (&data, &mng_pixbuf->iteration_max);
if (error)
SET_ERROR ("Unexpected end of file on TERM chunk")
}
@@ -226,8 +278,8 @@
// loading a PNG stream
if (loader)
{
- fseek (file, -8, SEEK_CUR);
- if (!read_data (file, chunk_size+8+4, loader, error_msg))
+ data.offset -= 8;
+ if (!read_data (&data, chunk_size+8+4, loader, error_msg))
error = TRUE;
else if (chunk_id == MNG_UINT_IEND)
{
@@ -240,7 +292,7 @@
}
}
- fseek (file, offset, SEEK_SET);
+ data.offset = chunk_offset;
first_read = FALSE;
} while (chunk_id != MNG_UINT_MEND && !error);
@@ -249,11 +301,11 @@
g_object_unref (G_OBJECT (mng_pixbuf));
return NULL;
}
- #undef SET_ERROR
-
return GDK_PIXBUF_ANIMATION (mng_pixbuf);
}
+#undef SET_ERROR
+
static gboolean ygdk_mng_pixbuf_is_static_image (GdkPixbufAnimation *anim)
{
return FALSE;
@@ -314,7 +366,7 @@
static int ygdk_mng_pixbuf_iter_get_delay_time (GdkPixbufAnimationIter *iter)
{
YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter);
- int delay = mng_iter->mng_pixbuf->ticks_per_second;
+ int delay = 1000.0 / mng_iter->mng_pixbuf->ticks_per_second;
if (mng_iter->cur_frame == g_list_length (mng_iter->mng_pixbuf->frames)-1)
delay += mng_iter->mng_pixbuf->last_frame_delay;
return delay;
Modified: trunk/gtk/src/ygdkmngloader.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygdkmngloader.h?rev=41406&r1=41405&r2=41406&view=diff
==============================================================================
--- trunk/gtk/src/ygdkmngloader.h (original)
+++ trunk/gtk/src/ygdkmngloader.h Fri Oct 12 14:35:29 2007
@@ -44,8 +44,10 @@
GdkPixbufAnimationClass parent_class;
} YGdkMngPixbufClass;
-GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_file (const gchar *filename, GError **error_msg);
+GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_file (const gchar *filename, GError **error);
+GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_data (const guint8 *data, long size, GError **error);
gboolean ygdk_mng_pixbuf_is_file_mng (const gchar *filename);
+gboolean ygdk_mng_pixbuf_is_data_mng (const guint8 *data, long size);
GType ygdk_mng_pixbuf_get_type (void) G_GNUC_CONST;
Modified: trunk/gtk/tests/Image.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/tests/Image.ycp?rev=41406&r1=41405&r2=41406&view=diff
==============================================================================
--- trunk/gtk/tests/Image.ycp (original)
+++ trunk/gtk/tests/Image.ycp Fri Oct 12 14:35:29 2007
@@ -1,5 +1,5 @@
// Image test
-string filename = "image.gif";
+string filename = "tests/image.gif";
{
UI::OpenDialog (
Modified: trunk/gtk/tests/ImageMng.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/tests/ImageMng.ycp?rev=41406&r1=41405&r2=41406&view=diff
==============================================================================
--- trunk/gtk/tests/ImageMng.ycp (original)
+++ trunk/gtk/tests/ImageMng.ycp Fri Oct 12 14:35:29 2007
@@ -1,4 +1,6 @@
// Image test
+// TODO: make it getting the filename as an argument
+
{
UI::OpenDialog (
`VBox (
@@ -10,8 +12,14 @@
`Frame ("Which MNG file:",
`RadioButtonGroup (`id(`rb),
`VBox(
- `Left (`RadioButton(`id (`endless), `opt(`notify), "&Endless")),
- `Left (`RadioButton(`id (`loop3), `opt(`notify), "&Loop 3"))
+ `Left (`RadioButton(`id (`movie1), `opt(`notify), "&Movie1")),
+ `Left (`RadioButton(`id (`movie2), `opt(`notify), "&Movie2")),
+ `Left (`RadioButton(`id (`movie3), `opt(`notify), "&Movie3")),
+ `Left (`RadioButton(`id (`movie4), `opt(`notify), "&Movie4")),
+ `Left (`RadioButton(`id (`movie5), `opt(`notify), "&Movie5")),
+ `Left (`RadioButton(`id (`movie6), `opt(`notify), "&Movie6")),
+ `Left (`RadioButton(`id (`movie7), `opt(`notify), "&Movie7")),
+ `Left (`RadioButton(`id (`movie8), `opt(`notify), "&Movie8"))
)
)
),
@@ -52,10 +60,26 @@
}
string filename = "";
- if ((boolean) UI::QueryWidget(`id(`loop3), `Value))
- filename = "movie-loop3.mng";
+ if ((boolean) UI::QueryWidget(`id(`movie1), `Value))
+ filename = "tests/movie1.mng";
+ else if ((boolean) UI::QueryWidget(`id(`movie2), `Value))
+ filename = "tests/movie2.mng";
+ else if ((boolean) UI::QueryWidget(`id(`movie3), `Value))
+ filename = "tests/movie3.mng";
+ else if ((boolean) UI::QueryWidget(`id(`movie4), `Value))
+ filename = "tests/movie4.mng";
+ else if ((boolean) UI::QueryWidget(`id(`movie5), `Value))
+ filename = "tests/movie5.mng";
+ else if ((boolean) UI::QueryWidget(`id(`movie6), `Value))
+ filename = "tests/movie6.mng";
+ else if ((boolean) UI::QueryWidget(`id(`movie7), `Value))
+ filename = "tests/movie7.mng";
else
- filename = "movie-endless.mng";
+ filename = "tests/movie8.mng";
+
+ // to test inline images, uncomment next line and pass it to `Image
+ //byteblock data = (byteblock) SCR::Read (.target.byte, filename);
+
UI::ReplaceWidget (`replace_image,
`Image (`opt (`animated, effect_opt, zerowidth, zeroheight),
filename, filename + " not found"));
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org