app: add xcf_read_component() and xcf_write_component()

which dispatch to endian-aware xcf_read/write_int8/int16/int32/int64()
This commit is contained in:
Michael Natterer 2017-09-16 17:58:30 +02:00
parent 77bf6313c3
commit 4ff911f84d
4 changed files with 235 additions and 55 deletions

View File

@ -32,6 +32,42 @@
#define MAX_XCF_STRING_LEN (16L * 1024 * 1024)
guint
xcf_read_int8 (XcfInfo *info,
guint8 *data,
gint count)
{
gsize bytes_read;
g_input_stream_read_all (info->input, data, count,
&bytes_read, NULL, NULL);
info->cp += bytes_read;
return bytes_read;
}
guint
xcf_read_int16 (XcfInfo *info,
guint16 *data,
gint count)
{
guint total = 0;
if (count > 0)
{
total += xcf_read_int8 (info, (guint8 *) data, count * 2);
while (count--)
{
*data = g_ntohs (*data);
data++;
}
}
return total;
}
guint
xcf_read_int32 (XcfInfo *info,
guint32 *data,
@ -53,6 +89,27 @@ xcf_read_int32 (XcfInfo *info,
return total;
}
guint
xcf_read_int64 (XcfInfo *info,
guint64 *data,
gint count)
{
guint total = 0;
if (count > 0)
{
total += xcf_read_int8 (info, (guint8 *) data, count * 8);
while (count--)
{
*data = GINT64_FROM_BE (*data);
data++;
}
}
return total;
}
guint
xcf_read_offset (XcfInfo *info,
goffset *data,
@ -98,21 +155,6 @@ xcf_read_float (XcfInfo *info,
return xcf_read_int32 (info, (guint32 *) ((void *) data), count);
}
guint
xcf_read_int8 (XcfInfo *info,
guint8 *data,
gint count)
{
gsize bytes_read;
g_input_stream_read_all (info->input, data, count,
&bytes_read, NULL, NULL);
info->cp += bytes_read;
return bytes_read;
}
guint
xcf_read_string (XcfInfo *info,
gchar **data,
@ -156,3 +198,30 @@ xcf_read_string (XcfInfo *info,
return total;
}
guint
xcf_read_component (XcfInfo *info,
gint bpc,
guint8 *data,
gint count)
{
switch (bpc)
{
case 8:
return xcf_read_int8 (info, data, count);
case 16:
return xcf_read_int16 (info, (guint16 *) data, count);
case 32:
return xcf_read_int32 (info, (guint32 *) data, count);
case 64:
return xcf_read_int64 (info, (guint64 *) data, count);
default:
break;
}
return 0;
}

View File

@ -19,21 +19,31 @@
#define __XCF_READ_H__
guint xcf_read_int32 (XcfInfo *info,
guint32 *data,
gint count);
guint xcf_read_offset (XcfInfo *info,
goffset *data,
gint count);
guint xcf_read_float (XcfInfo *info,
gfloat *data,
gint count);
guint xcf_read_int8 (XcfInfo *info,
guint8 *data,
gint count);
guint xcf_read_string (XcfInfo *info,
gchar **data,
gint count);
guint xcf_read_int8 (XcfInfo *info,
guint8 *data,
gint count);
guint xcf_read_int16 (XcfInfo *info,
guint16 *data,
gint count);
guint xcf_read_int32 (XcfInfo *info,
guint32 *data,
gint count);
guint xcf_read_int64 (XcfInfo *info,
guint64 *data,
gint count);
guint xcf_read_offset (XcfInfo *info,
goffset *data,
gint count);
guint xcf_read_float (XcfInfo *info,
gfloat *data,
gint count);
guint xcf_read_string (XcfInfo *info,
gchar **data,
gint count);
guint xcf_read_component (XcfInfo *info,
gint bpc,
guint8 *data,
gint count);
#endif /* __XCF_READ_H__ */

View File

@ -29,6 +29,56 @@
#include "gimp-intl.h"
guint
xcf_write_int8 (XcfInfo *info,
const guint8 *data,
gint count,
GError **error)
{
GError *my_error = NULL;
gsize bytes_written;
if (! g_output_stream_write_all (info->output, data, count,
&bytes_written, NULL, &my_error))
{
g_propagate_prefixed_error (error, my_error,
_("Error writing XCF: "));
}
info->cp += bytes_written;
return bytes_written;
}
guint
xcf_write_int16 (XcfInfo *info,
const guint16 *data,
gint count,
GError **error)
{
GError *tmp_error = NULL;
gint i;
if (count > 0)
{
for (i = 0; i < count; i++)
{
guint16 tmp = g_htons (data[i]);
xcf_write_int8 (info, (const guint8 *) &tmp, 2, &tmp_error);
if (tmp_error)
{
g_propagate_error (error, tmp_error);
return i * 2;
}
}
}
return count * 2;
}
guint
xcf_write_int32 (XcfInfo *info,
const guint32 *data,
@ -58,6 +108,35 @@ xcf_write_int32 (XcfInfo *info,
return count * 4;
}
guint
xcf_write_int64 (XcfInfo *info,
const guint64 *data,
gint count,
GError **error)
{
GError *tmp_error = NULL;
gint i;
if (count > 0)
{
for (i = 0; i < count; i++)
{
guint64 tmp = GINT64_TO_BE (data[i]);
xcf_write_int8 (info, (const guint8 *) &tmp, 8, &tmp_error);
if (tmp_error)
{
g_propagate_error (error, tmp_error);
return i * 8;
}
}
}
return count * 8;
}
guint
xcf_write_offset (XcfInfo *info,
const goffset *data,
@ -126,27 +205,6 @@ xcf_write_float (XcfInfo *info,
error);
}
guint
xcf_write_int8 (XcfInfo *info,
const guint8 *data,
gint count,
GError **error)
{
GError *my_error = NULL;
gsize bytes_written;
if (! g_output_stream_write_all (info->output, data, count,
&bytes_written, NULL, &my_error))
{
g_propagate_prefixed_error (error, my_error,
_("Error writing XCF: "));
}
info->cp += bytes_written;
return bytes_written;
}
guint
xcf_write_string (XcfInfo *info,
gchar **data,
@ -188,3 +246,33 @@ xcf_write_string (XcfInfo *info,
return total;
}
guint
xcf_write_component (XcfInfo *info,
gint bpc,
const guint8 *data,
gint count,
GError **error)
{
switch (bpc)
{
case 8:
return xcf_write_int8 (info, data, count, error);
case 16:
return xcf_write_int16 (info, (const guint16 *) data, count, error);
case 32:
return xcf_write_int32 (info, (const guint32 *) data, count, error);
case 64:
return xcf_write_int64 (info, (const guint64 *) data, count, error);
default:
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Error writing XCF: unsupported BPC when writing pixel: %d"),
bpc);
}
return 0;
}

View File

@ -19,10 +19,22 @@
#define __XCF_WRITE_H__
guint xcf_write_int8 (XcfInfo *info,
const guint8 *data,
gint count,
GError **error);
guint xcf_write_int16 (XcfInfo *info,
const guint16 *data,
gint count,
GError **error);
guint xcf_write_int32 (XcfInfo *info,
const guint32 *data,
gint count,
GError **error);
guint xcf_write_int64 (XcfInfo *info,
const guint64 *data,
gint count,
GError **error);
guint xcf_write_offset (XcfInfo *info,
const goffset *data,
gint count,
@ -34,14 +46,15 @@ guint xcf_write_float (XcfInfo *info,
const gfloat *data,
gint count,
GError **error);
guint xcf_write_int8 (XcfInfo *info,
const guint8 *data,
gint count,
GError **error);
guint xcf_write_string (XcfInfo *info,
gchar **data,
gint count,
GError **error);
guint xcf_write_component (XcfInfo *info,
gint bpc,
const guint8 *data,
gint count,
GError **error);
#endif /* __XCF_WRITE_H__ */