forked from ImageOptim/libimagequant
-
Notifications
You must be signed in to change notification settings - Fork 0
/
libimagequant.cs
164 lines (136 loc) · 6.45 KB
/
libimagequant.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
This is an example demonstrating use of libimagequant from C#.
This example code can be freely copied under CC0 (public domain) license.
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct liq_color
{
public byte r, g, b, a;
};
[StructLayout(LayoutKind.Sequential)]
struct liq_palette
{
public int count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public liq_color[] entries;
};
enum liq_error
{
LIQ_OK = 0,
LIQ_QUALITY_TOO_LOW = 99,
LIQ_VALUE_OUT_OF_RANGE = 100,
LIQ_OUT_OF_MEMORY,
LIQ_ABORTED,
LIQ_BITMAP_NOT_AVAILABLE,
LIQ_BUFFER_TOO_SMALL,
LIQ_INVALID_POINTER,
};
namespace liq
{
using liq_attr_ptr = IntPtr;
using liq_image_ptr = IntPtr;
using liq_result_ptr = IntPtr;
using size_t = UIntPtr;
class Liq
{
[DllImport(@"imagequant.dll")]
public static extern liq_attr_ptr liq_attr_create();
[DllImport(@"imagequant.dll")]
public static extern liq_attr_ptr liq_attr_copy(liq_attr_ptr attr);
[DllImport(@"imagequant.dll")]
public static extern void liq_attr_destroy(liq_attr_ptr attr);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_set_max_colors(liq_attr_ptr attr, int colors);
[DllImport(@"imagequant.dll")]
public static extern int liq_get_max_colors(liq_attr_ptr attr);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_set_speed(liq_attr_ptr attr, int speed);
[DllImport(@"imagequant.dll")]
public static extern int liq_get_speed(liq_attr_ptr attr);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_set_min_opacity(liq_attr_ptr attr, int min);
[DllImport(@"imagequant.dll")]
public static extern int liq_get_min_opacity(liq_attr_ptr attr);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_set_min_posterization(liq_attr_ptr attr, int bits);
[DllImport(@"imagequant.dll")]
public static extern int liq_get_min_posterization(liq_attr_ptr attr);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_set_quality(liq_attr_ptr attr, int minimum, int maximum);
[DllImport(@"imagequant.dll")]
public static extern int liq_get_min_quality(liq_attr_ptr attr);
[DllImport(@"imagequant.dll")]
public static extern int liq_get_max_quality(liq_attr_ptr attr);
[DllImport(@"imagequant.dll")]
public static extern void liq_set_last_index_transparent(liq_attr_ptr attr, int is_last);
[DllImport(@"imagequant.dll")]
public static extern liq_image_ptr liq_image_create_rgba(liq_attr_ptr attr, [In, MarshalAs(UnmanagedType.LPArray)] byte[] bitmap, int width, int height, double gamma);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_image_set_memory_ownership(liq_image_ptr image, int ownership_flags);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_image_add_fixed_color(liq_image_ptr img, liq_color color);
[DllImport(@"imagequant.dll")]
public static extern int liq_image_get_width(liq_image_ptr img);
[DllImport(@"imagequant.dll")]
public static extern int liq_image_get_height(liq_image_ptr img);
[DllImport(@"imagequant.dll")]
public static extern void liq_image_destroy(liq_image_ptr img);
[DllImport(@"imagequant.dll")]
public static extern liq_result_ptr liq_quantize_image(liq_attr_ptr attr, liq_image_ptr input_image);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_set_dithering_level(liq_result_ptr res, float dither_level);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_set_output_gamma(liq_result_ptr res, double gamma);
[DllImport(@"imagequant.dll")]
public static extern double liq_get_output_gamma(liq_result_ptr res);
[DllImport(@"imagequant.dll")]
public static extern IntPtr liq_get_palette(liq_result_ptr res);
[DllImport(@"imagequant.dll")]
public static extern liq_error liq_write_remapped_image(liq_result_ptr res, liq_image_ptr input_image, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] buffer, size_t buffer_size);
[DllImport(@"imagequant.dll")]
public static extern double liq_get_quantization_error(liq_result_ptr res);
[DllImport(@"imagequant.dll")]
public static extern int liq_get_quantization_quality(liq_result_ptr res);
[DllImport(@"imagequant.dll")]
public static extern double liq_get_remapping_error(liq_result_ptr res);
[DllImport(@"imagequant.dll")]
public static extern int liq_get_remapping_quality(liq_result_ptr res);
[DllImport(@"imagequant.dll")]
public static extern void liq_result_destroy(liq_result_ptr res);
[DllImport(@"imagequant.dll")]
public static extern int liq_version();
static void Main(string[] args)
{
Console.WriteLine("library version: {0}", liq_version());
int width = 3;
int height = 1;
var attr = liq_attr_create();
if (attr == IntPtr.Zero) throw new Exception("can't create attr");
byte[] bitmap = { // R, G, B, A, R, G, B, A, ...
111, 222, 33, 255,
255, 0, 255, 255,
255, 0, 255, 255,
};
var img = liq_image_create_rgba(attr, bitmap, width, height, 0);
if (img == IntPtr.Zero) throw new Exception("can't create image");
var res = liq_quantize_image(attr, img);
if (res == IntPtr.Zero) throw new Exception("can't quantize image");
var buffer_size = width * height;
var remapped = new byte[buffer_size];
var err = liq_write_remapped_image(res, img, remapped, (UIntPtr)buffer_size);
if (err != liq_error.LIQ_OK)
{
throw new Exception("remapping error");
}
Console.WriteLine("first pixel is {0}th palette entry", remapped[0]);
liq_palette pal = (liq_palette)Marshal.PtrToStructure(liq_get_palette(res), typeof(liq_palette));
Console.WriteLine("palette entries: {0}; red of first entry: {1}", pal.count, pal.entries[0].r);
liq_image_destroy(img);
liq_result_destroy(res);
liq_attr_destroy(attr);
}
}
}