png: add a combo-box for specifying png bitdepth/variant

When working in high bitdepth, manually changing precision to 8bit or 16bit is
an extraenous step, this adds a conversion step - but doesn't permit dithering
- and also doesn't permit using the palette modes of PNG. However it makes
workflows with single precision linear floating point much more usable.
parent 7236ca59
......@@ -77,6 +77,18 @@
* Structures...
*/
typedef enum _PngExportformat {
PNG_FORMAT_AUTO = 0,
PNG_FORMAT_RGB8,
PNG_FORMAT_GRAY8,
PNG_FORMAT_RGBA8,
PNG_FORMAT_GRAYA8,
PNG_FORMAT_RGB16,
PNG_FORMAT_GRAY16,
PNG_FORMAT_RGBA16,
PNG_FORMAT_GRAYA16
} PngExportFormat;
typedef struct
{
gboolean interlaced;
......@@ -92,6 +104,7 @@ typedef struct
gboolean save_xmp;
gboolean save_iptc;
gboolean save_thumbnail;
PngExportFormat export_format;
}
PngSaveVals;
......@@ -106,6 +119,7 @@ typedef struct
GtkWidget *phys;
GtkWidget *time;
GtkWidget *comment;
GtkWidget *pixelformat;
GtkWidget *save_transp_pixels;
GtkAdjustment *compression_level;
GtkWidget *save_exif;
......@@ -201,7 +215,8 @@ static const PngSaveVals defaults =
TRUE, /* save exif */
TRUE, /* save xmp */
TRUE, /* save iptc */
TRUE /* save thumbnail */
TRUE, /* save thumbnail */
PNG_FORMAT_AUTO
};
static PngSaveVals pngvals;
......@@ -1564,103 +1579,153 @@ save_image (const gchar *filename,
for (i = 0; i < 256; i++)
remap[i] = i;
/*
* Set color type and remember bytes per pixel count
*/
switch (type)
if (pngvals.export_format == PNG_FORMAT_AUTO)
{
case GIMP_RGB_IMAGE:
color_type = PNG_COLOR_TYPE_RGB;
if (bit_depth == 8)
{
if (linear)
file_format = babl_format ("RGB u8");
else
file_format = babl_format ("R'G'B' u8");
}
else
{
if (linear)
file_format = babl_format ("RGB u16");
else
file_format = babl_format ("R'G'B' u16");
}
break;
case GIMP_RGBA_IMAGE:
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
if (bit_depth == 8)
{
if (linear)
file_format = babl_format ("RGBA u8");
else
file_format = babl_format ("R'G'B'A u8");
}
else
{
if (linear)
file_format = babl_format ("RGBA u16");
else
file_format = babl_format ("R'G'B'A u16");
}
break;
case GIMP_GRAY_IMAGE:
color_type = PNG_COLOR_TYPE_GRAY;
if (bit_depth == 8)
{
if (linear)
file_format = babl_format ("Y u8");
else
file_format = babl_format ("Y' u8");
}
else
{
if (linear)
file_format = babl_format ("Y u16");
else
file_format = babl_format ("Y' u16");
}
break;
case GIMP_GRAYA_IMAGE:
color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
if (bit_depth == 8)
{
if (linear)
file_format = babl_format ("YA u8");
else
file_format = babl_format ("Y'A u8");
}
else
{
if (linear)
file_format = babl_format ("YA u16");
else
file_format = babl_format ("Y'A u16");
}
break;
case GIMP_INDEXED_IMAGE:
color_type = PNG_COLOR_TYPE_PALETTE;
file_format = gimp_drawable_get_format (drawable_ID);
pngg.has_plte = TRUE;
pngg.palette = (png_colorp) gimp_image_get_colormap (image_ID,
&pngg.num_palette);
bit_depth = get_bit_depth_for_palette (pngg.num_palette);
break;
case GIMP_INDEXEDA_IMAGE:
color_type = PNG_COLOR_TYPE_PALETTE;
file_format = gimp_drawable_get_format (drawable_ID);
/* fix up transparency */
bit_depth = respin_cmap (pp, info, remap, image_ID, drawable_ID);
break;
default:
g_set_error (error, 0, 0, "Image type can't be exported as PNG");
return FALSE;
/*
* Set color type and remember bytes per pixel count
*/
switch (type)
{
case GIMP_RGB_IMAGE:
color_type = PNG_COLOR_TYPE_RGB;
if (bit_depth == 8)
{
if (linear)
file_format = babl_format ("RGB u8");
else
file_format = babl_format ("R'G'B' u8");
}
else
{
if (linear)
file_format = babl_format ("RGB u16");
else
file_format = babl_format ("R'G'B' u16");
}
break;
case GIMP_RGBA_IMAGE:
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
if (bit_depth == 8)
{
if (linear)
file_format = babl_format ("RGBA u8");
else
file_format = babl_format ("R'G'B'A u8");
}
else
{
if (linear)
file_format = babl_format ("RGBA u16");
else
file_format = babl_format ("R'G'B'A u16");
}
break;
case GIMP_GRAY_IMAGE:
color_type = PNG_COLOR_TYPE_GRAY;
if (bit_depth == 8)
{
if (linear)
file_format = babl_format ("Y u8");
else
file_format = babl_format ("Y' u8");
}
else
{
if (linear)
file_format = babl_format ("Y u16");
else
file_format = babl_format ("Y' u16");
}
break;
case GIMP_GRAYA_IMAGE:
color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
if (bit_depth == 8)
{
if (linear)
file_format = babl_format ("YA u8");
else
file_format = babl_format ("Y'A u8");
}
else
{
if (linear)
file_format = babl_format ("YA u16");
else
file_format = babl_format ("Y'A u16");
}
break;
case GIMP_INDEXED_IMAGE:
color_type = PNG_COLOR_TYPE_PALETTE;
file_format = gimp_drawable_get_format (drawable_ID);
pngg.has_plte = TRUE;
pngg.palette = (png_colorp) gimp_image_get_colormap (image_ID,
&pngg.num_palette);
bit_depth = get_bit_depth_for_palette (pngg.num_palette);
break;
case GIMP_INDEXEDA_IMAGE:
color_type = PNG_COLOR_TYPE_PALETTE;
file_format = gimp_drawable_get_format (drawable_ID);
/* fix up transparency */
bit_depth = respin_cmap (pp, info, remap, image_ID, drawable_ID);
break;
default:
g_set_error (error, 0, 0, "Image type can't be exported as PNG");
return FALSE;
}
}
else
{
switch (pngvals.export_format)
{
case PNG_FORMAT_RGB8:
color_type = PNG_COLOR_TYPE_RGB;
file_format = babl_format ("R'G'B' u8");
bit_depth = 8;
break;
case PNG_FORMAT_GRAY8:
color_type = PNG_COLOR_TYPE_GRAY;
file_format = babl_format ("Y' u8");
bit_depth = 8;
break;
case PNG_FORMAT_AUTO: // shut up gcc
case PNG_FORMAT_RGBA8:
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
file_format = babl_format ("R'G'B'A u8");
bit_depth = 8;
break;
case PNG_FORMAT_GRAYA8:
color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
file_format = babl_format ("Y'A u8");
bit_depth = 8;
break;
case PNG_FORMAT_RGB16:
color_type = PNG_COLOR_TYPE_RGB;
file_format = babl_format ("R'G'B' u16");
bit_depth = 16;
break;
case PNG_FORMAT_GRAY16:
color_type = PNG_COLOR_TYPE_GRAY;
file_format = babl_format ("Y' u16");
bit_depth = 16;
break;
case PNG_FORMAT_RGBA16:
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
file_format = babl_format ("R'G'B'A u16");
bit_depth = 16;
break;
case PNG_FORMAT_GRAYA16:
color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
file_format = babl_format ("Y'A u16");
bit_depth = 16;
break;
}
}
bpp = babl_format_get_bytes_per_pixel (file_format);
......@@ -2234,6 +2299,13 @@ toggle_button_init (GtkBuilder *builder,
return toggle;
}
static void pixformat_changed (GtkWidget *widget,
void *foo)
{
PngExportFormat *ep = foo;
*ep = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
}
static gboolean
save_dialog (gint32 image_ID,
gboolean alpha)
......@@ -2333,6 +2405,21 @@ save_dialog (gint32 image_ID,
G_CALLBACK (gimp_int_adjustment_update),
&pngvals.compression_level);
/* Compression level scale */
pg.pixelformat =
GTK_WIDGET (gtk_builder_get_object (builder, "pixelformat-combo"));
gtk_combo_box_set_active (GTK_COMBO_BOX (pg.pixelformat), pngvals.export_format);
g_signal_connect (pg.pixelformat, "changed",
G_CALLBACK (pixformat_changed),
&pngvals.export_format);
#if 0
gtk_adjustment_set_value (pg.compression_level, pngvals.compression_level);
g_signal_connect (pg.compression_level, "value-changed",
G_CALLBACK (gimp_int_adjustment_update),
&pngvals.compression_level);
#endif
/* Load/save defaults buttons */
g_signal_connect_swapped (gtk_builder_get_object (builder, "load-defaults"),
"clicked",
......
......@@ -12,7 +12,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="n_rows">11</property>
<property name="n_rows">12</property>
<property name="n_columns">3</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
......@@ -142,21 +142,6 @@
<property name="bottom_attach">8</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="compression-level-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Co_mpression level:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">compression-level-spin</property>
</object>
<packing>
<property name="top_attach">8</property>
<property name="bottom_attach">9</property>
<property name="x_options"/>
</packing>
</child>
<child>
<object class="GtkHScale" id="compression-level-scale">
<property name="visible">True</property>
......@@ -167,8 +152,8 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">8</property>
<property name="bottom_attach">9</property>
<property name="top_attach">9</property>
<property name="bottom_attach">10</property>
</packing>
</child>
<child>
......@@ -186,8 +171,8 @@
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">8</property>
<property name="bottom_attach">9</property>
<property name="top_attach">9</property>
<property name="bottom_attach">10</property>
<property name="x_options"/>
</packing>
</child>
......@@ -228,8 +213,8 @@
</object>
<packing>
<property name="right_attach">3</property>
<property name="top_attach">10</property>
<property name="bottom_attach">11</property>
<property name="top_attach">11</property>
<property name="bottom_attach">12</property>
</packing>
</child>
<child>
......@@ -316,8 +301,46 @@
</object>
<packing>
<property name="right_attach">3</property>
<property name="top_attach">10</property>
<property name="bottom_attach">11</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="compression-level-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Co_mpression level:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">compression-level-spin</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="top_attach">9</property>
<property name="bottom_attach">10</property>
<property name="x_options"/>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="pixelformat-combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<items>
<item translatable="yes">automatic pixelformat</item>
<item translatable="yes">8bpc RGB</item>
<item translatable="yes">8bpc GRAY</item>
<item translatable="yes">8bpc RGBA</item>
<item translatable="yes">8bpc GRAYA</item>
<item translatable="yes">16bpc RGB</item>
<item translatable="yes">16bpc GRAY</item>
<item translatable="yes">16bpc RGBA</item>
<item translatable="yes">16bpc GRAYA</item>
</items>
</object>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">3</property>
<property name="top_attach">8</property>
<property name="bottom_attach">9</property>
</packing>
</child>
</object>
......
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