Download code

Jump to: navigation, search

Back to Floyd-Steinberg_dithering_(C)

Download for Windows: zip

Download for UNIX: zip, tar.gz, tar.bz2

floyd_steinberg_dither_sample.c

  1 /* The authors of this work have released all rights to it and placed it
  2 in the public domain under the Creative Commons CC0 1.0 waiver
  3 (http://creativecommons.org/publicdomain/zero/1.0/).
  4 
  5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  6 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  7 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  8 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  9 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 10 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 11 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 12 
 13 Retrieved from: http://en.literateprograms.org/Floyd-Steinberg_dithering_(C)?oldid=19131
 14 */
 15 
 16 #include <stdio.h>
 17 #include <stdlib.h>
 18 #include "floyd_steinberg_dither.h"
 19 
 20 int main(int argc, char* argv[]) {
 21     int x, y;
 22     RGBImage image;
 23     RGBPalette palette;
 24     PalettizedImage result;
 25     FILE * raw_in, * raw_out;
 26 
 27     image.width = 100;
 28     image.height = 145;
 29     image.pixels = malloc(sizeof(RGBTriple) *
 30                    image.width * image.height);
 31 
 32     raw_in = fopen(argv[1], "rb");
 33     for(y = 0; y < image.height; y++) {
 34         for(x = 0; x < image.width; x++) {
 35             fread(&image.pixels[x + y*image.width],
 36                   3, 1, raw_in);
 37         }
 38     }
 39     fclose(raw_in);
 40 
 41     palette.size = 16;
 42     palette.table = malloc(sizeof(RGBTriple) * 16);
 43     palette.table[0].R = 149;
 44     palette.table[0].G = 91;
 45     palette.table[0].B = 110;
 46     palette.table[1].R = 176;
 47     palette.table[1].G = 116;
 48     palette.table[1].B = 137;
 49     palette.table[2].R = 17;
 50     palette.table[2].G = 11;
 51     palette.table[2].B = 15;
 52     palette.table[3].R = 63;
 53     palette.table[3].G = 47;
 54     palette.table[3].B = 69;
 55     palette.table[4].R = 93;
 56     palette.table[4].G = 75;
 57     palette.table[4].B = 112;
 58     palette.table[5].R = 47;
 59     palette.table[5].G = 62;
 60     palette.table[5].B = 24;
 61     palette.table[6].R = 76;
 62     palette.table[6].G = 90;
 63     palette.table[6].B = 55;
 64     palette.table[7].R = 190;
 65     palette.table[7].G = 212;
 66     palette.table[7].B = 115;
 67     palette.table[8].R = 160;
 68     palette.table[8].G = 176;
 69     palette.table[8].B = 87;
 70     palette.table[9].R = 116;
 71     palette.table[9].G = 120;
 72     palette.table[9].B = 87;
 73     palette.table[10].R = 245;
 74     palette.table[10].G = 246;
 75     palette.table[10].B = 225;
 76     palette.table[11].R = 148;
 77     palette.table[11].G = 146;
 78     palette.table[11].B = 130;
 79     palette.table[12].R = 200;
 80     palette.table[12].G = 195;
 81     palette.table[12].B = 180;
 82     palette.table[13].R = 36;
 83     palette.table[13].G = 32;
 84     palette.table[13].B = 27;
 85     palette.table[14].R = 87;
 86     palette.table[14].G = 54;
 87     palette.table[14].B = 45;
 88     palette.table[15].R = 121;
 89     palette.table[15].G = 72;
 90     palette.table[15].B = 72;
 91 
 92     result = FloydSteinbergDither(image, palette);
 93 
 94     raw_out = fopen(argv[2], "wb");
 95     for(y = 0; y < result.height; y++) {
 96         for(x = 0; x < result.width; x++) {
 97             fwrite(&palette.table[result.pixels[x + y*image.width]],
 98                    3, 1, raw_out);
 99         }
100     }
101     fclose(raw_out);
102 
103     return 0;
104 }


hijacker
hijacker
hijacker
hijacker

floyd_steinberg_dither.c

 1 /* The authors of this work have released all rights to it and placed it
 2 in the public domain under the Creative Commons CC0 1.0 waiver
 3 (http://creativecommons.org/publicdomain/zero/1.0/).
 4 
 5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 6 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 7 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 8 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 9 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
11 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12 
13 Retrieved from: http://en.literateprograms.org/Floyd-Steinberg_dithering_(C)?oldid=19131
14 */
15 
16 #include <stdlib.h>
17 #include "floyd_steinberg_dither.h"
18 
19 #define plus_truncate_uchar(a, b) \
20     if (((int)(a)) + (b) < 0) \
21         (a) = 0; \
22     else if (((int)(a)) + (b) > 255) \
23         (a) = 255; \
24     else \
25         (a) += (b);
26 
27 
28 static
29 unsigned char FindNearestColor(RGBTriple color, RGBPalette palette) {
30     int i, distanceSquared, minDistanceSquared, bestIndex = 0;
31     minDistanceSquared = 255*255 + 255*255 + 255*255 + 1;
32     for (i=0; i<palette.size; i++) {
33         int Rdiff = ((int)color.R) - palette.table[i].R;
34         int Gdiff = ((int)color.G) - palette.table[i].G;
35         int Bdiff = ((int)color.B) - palette.table[i].B;
36         distanceSquared = Rdiff*Rdiff + Gdiff*Gdiff + Bdiff*Bdiff;
37         if (distanceSquared < minDistanceSquared) {
38             minDistanceSquared = distanceSquared;
39             bestIndex = i;
40         }
41     }
42     return bestIndex;
43 }
44 
45 #define compute_disperse(channel) \
46 error = ((int)(currentPixel->channel)) - palette.table[index].channel; \
47 if (x + 1 < image.width) { \
48     plus_truncate_uchar(image.pixels[(x+1) + (y+0)*image.width].channel, (error*7) >> 4); \
49 } \
50 if (y + 1 < image.height) { \
51     if (x - 1 > 0) { \
52         plus_truncate_uchar(image.pixels[(x-1) + (y+1)*image.width].channel, (error*3) >> 4); \
53     } \
54     plus_truncate_uchar(image.pixels[(x+0) + (y+1)*image.width].channel, (error*5) >> 4); \
55     if (x + 1 < image.width) { \
56         plus_truncate_uchar(image.pixels[(x+1) + (y+1)*image.width].channel, (error*1) >> 4); \
57     } \
58 }
59 
60 PalettizedImage FloydSteinbergDither(RGBImage image, RGBPalette palette)
61 
62 {
63     PalettizedImage result;
64     result.width = image.width;
65     result.height = image.height;
66     result.pixels = malloc(sizeof(unsigned char) * result.width * result.height);
67 
68     {
69     int x, y;
70     for(y = 0; y < image.height; y++) {
71         for(x = 0; x < image.width; x++) {
72         RGBTriple* currentPixel = &(image.pixels[x + y*image.width]);
73         unsigned char index = FindNearestColor(*currentPixel, palette);
74 	result.pixels[x + y*result.width] = index;
75 
76         {
77 	    int error;
78 	    compute_disperse(R);
79 	    compute_disperse(G);
80 	    compute_disperse(B);
81 	}
82         }
83     }
84     }
85     return result;
86 }
87 


hijacker
hijacker
hijacker
hijacker

build.log

1 /tmp/litprog2496240/floyd_steinberg_dither_sample.c: In function 'main':
2 /tmp/litprog2496240/floyd_steinberg_dither_sample.c:35:18: warning: ignoring return value of 'fread', declared with attribute warn_unused_result [-Wunused-result]


floyd_steinberg_dither.h

 1 /* The authors of this work have released all rights to it and placed it
 2 in the public domain under the Creative Commons CC0 1.0 waiver
 3 (http://creativecommons.org/publicdomain/zero/1.0/).
 4 
 5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 6 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 7 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 8 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 9 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
11 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12 
13 Retrieved from: http://en.literateprograms.org/Floyd-Steinberg_dithering_(C)?oldid=19131
14 */
15 
16 #ifndef _FLOYD_STEINBERG_DITHER_H_
17 
18 typedef struct {
19     unsigned char R, G, B;
20 } RGBTriple;
21 
22 typedef struct {
23     int size;
24     RGBTriple* table;
25 } RGBPalette;
26 
27 typedef struct {
28     int width, height;
29     RGBTriple* pixels;
30 } RGBImage;
31 
32 typedef struct {
33     int width, height;
34     unsigned char* pixels;
35 } PalettizedImage;
36 
37 PalettizedImage FloydSteinbergDither(RGBImage image, RGBPalette palette)
38 ;
39 
40 #endif /* #ifndef _FLOYD_STEINBERG_DITHER_H_ */


hijacker
hijacker
hijacker
hijacker