Commit a735ba0d authored by Michael Natterer's avatar Michael Natterer 😴

app: add code to read/write XCF tile data as big-endian

It was always supposed to be like that, but simply forgotten.
Fortunately, big-endian machines are almost extinct...

The new code is triggered with XCF version >= 12, but we will start
using that only after code review.
parent 4ff911f8
......@@ -2052,7 +2052,17 @@ xcf_load_tile (XcfInfo *info,
gint tile_size = bpp * tile_rect->width * tile_rect->height;
guchar *tile_data = g_alloca (tile_size);
xcf_read_int8 (info, tile_data, tile_size);
if (info->file_version <= 11)
{
xcf_read_int8 (info, tile_data, tile_size);
}
else
{
gint n_components = babl_format_get_n_components (format);
xcf_read_component (info, bpp / n_components, tile_data,
tile_size / n_components);
}
gegl_buffer_set (buffer, tile_rect, 0, format, tile_data,
GEGL_AUTO_ROWSTRIDE);
......@@ -2189,6 +2199,14 @@ xcf_load_tile_rle (XcfInfo *info,
}
}
if (info->file_version >= 12)
{
gint n_components = babl_format_get_n_components (format);
xcf_read_from_be (bpp / n_components, tile_data,
tile_size / n_components);
}
gegl_buffer_set (buffer, tile_rect, 0, format, tile_data,
GEGL_AUTO_ROWSTRIDE);
......@@ -2279,10 +2297,19 @@ xcf_load_tile_zlib (XcfInfo *info,
}
}
if (info->file_version >= 12)
{
gint n_components = babl_format_get_n_components (format);
xcf_read_from_be (bpp / n_components, tile_data,
tile_size / n_components);
}
gegl_buffer_set (buffer, tile_rect, 0, format, tile_data,
GEGL_AUTO_ROWSTRIDE);
inflateEnd (&strm);
return TRUE;
}
......
......@@ -225,3 +225,44 @@ xcf_read_component (XcfInfo *info,
return 0;
}
void
xcf_read_from_be (gint bpc,
guint8 *data,
gint count)
{
gint i;
switch (bpc)
{
case 8:
break;
case 16:
{
guint16 *d = (guint16 *) data;
for (i = 0; i < count; i++)
d[i] = g_ntohs (d[i]);
}
break;
case 32:
{
guint32 *d = (guint32 *) data;
for (i = 0; i < count; i++)
d[i] = g_ntohl (d[i]);
}
break;
case 64:
{
guint64 *d = (guint64 *) data;
for (i = 0; i < count; i++)
d[i] = GINT64_FROM_BE (d[i]);
}
break;
}
}
......@@ -45,5 +45,9 @@ guint xcf_read_component (XcfInfo *info,
guint8 *data,
gint count);
void xcf_read_from_be (gint bpc,
guint8 *data,
gint count);
#endif /* __XCF_READ_H__ */
......@@ -186,6 +186,15 @@ static gboolean xcf_save_vectors (XcfInfo *info,
} \
} G_STMT_END
#define xcf_write_component_check_error(info, bpc, data, count) G_STMT_START { \
xcf_write_component (info, bpc, data, count, &tmp_error); \
if (tmp_error) \
{ \
g_propagate_error (error, tmp_error); \
return FALSE; \
} \
} G_STMT_END
#define xcf_write_prop_type_check_error(info, prop_type) G_STMT_START { \
guint32 _prop_int32 = prop_type; \
xcf_write_int32_check_error (info, &_prop_int32, 1); \
......@@ -1628,7 +1637,17 @@ xcf_save_tile (XcfInfo *info,
gegl_buffer_get (buffer, tile_rect, 1.0, format, tile_data,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
xcf_write_int8_check_error (info, tile_data, tile_size);
if (info->file_version <= 11)
{
xcf_write_int8_check_error (info, tile_data, tile_size);
}
else
{
gint n_components = babl_format_get_n_components (format);
xcf_write_component_check_error (info, bpp / n_components, tile_data,
tile_size / n_components);
}
return TRUE;
}
......@@ -1651,6 +1670,14 @@ xcf_save_tile_rle (XcfInfo *info,
gegl_buffer_get (buffer, tile_rect, 1.0, format, tile_data,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
if (info->file_version >= 12)
{
gint n_components = babl_format_get_n_components (format);
xcf_write_to_be (bpp / n_components, tile_data,
tile_size / n_components);
}
for (i = 0; i < bpp; i++)
{
const guchar *data = tile_data + i;
......@@ -1779,6 +1806,14 @@ xcf_save_tile_zlib (XcfInfo *info,
gegl_buffer_get (buffer, tile_rect, 1.0, format, tile_data,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
if (info->file_version >= 12)
{
gint n_components = babl_format_get_n_components (format);
xcf_write_to_be (bpp / n_components, tile_data,
tile_size / n_components);
}
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
......
......@@ -276,3 +276,44 @@ xcf_write_component (XcfInfo *info,
return 0;
}
void
xcf_write_to_be (gint bpc,
guint8 *data,
gint count)
{
gint i;
switch (bpc)
{
case 8:
break;
case 16:
{
guint16 *d = (guint16 *) data;
for (i = 0; i < count; i++)
d[i] = g_htons (d[i]);
}
break;
case 32:
{
guint32 *d = (guint32 *) data;
for (i = 0; i < count; i++)
d[i] = g_htonl (d[i]);
}
break;
case 64:
{
guint64 *d = (guint64 *) data;
for (i = 0; i < count; i++)
d[i] = GINT64_TO_BE (d[i]);
}
break;
}
}
......@@ -56,5 +56,9 @@ guint xcf_write_component (XcfInfo *info,
gint count,
GError **error);
void xcf_write_to_be (gint bpc,
guint8 *data,
gint count);
#endif /* __XCF_WRITE_H__ */
......@@ -78,7 +78,8 @@ static GimpXcfLoaderFunc * const xcf_loaders[] =
xcf_load_image, /* version 8 */
xcf_load_image, /* version 9 */
xcf_load_image, /* version 10 */
xcf_load_image /* version 11 */
xcf_load_image, /* version 11 */
xcf_load_image /* version 12 */
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment