Skip to content

Commit 1a931d9

Browse files
author
Sebastien Bourdeauducq
committedNov 16, 2011
Image loading library (WIP)
1 parent 03214ca commit 1a931d9

File tree

7 files changed

+430
-0
lines changed

7 files changed

+430
-0
lines changed
 

‎src/pixbuf/dither.c

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Flickernoise
3+
* Copyright (C) 2011 Sebastien Bourdeauducq
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, version 3 of the License.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <stdlib.h>
19+
20+
#include "../color.h"
21+
22+
static void floyd_steinberg(int *pic, int width, int height)
23+
{
24+
int x, y;
25+
int offset;
26+
int old_r, old_g, old_b;
27+
int new_r, new_g, new_b;
28+
int qe_r, qe_g, qe_b;
29+
30+
for(y=0;y<height;y++)
31+
for(x=0;x<width;x++) {
32+
offset = 3*(width*y+x);
33+
old_r = pic[offset];
34+
old_g = pic[offset+1];
35+
old_b = pic[offset+2];
36+
if(old_r > 0x00f80000)
37+
new_r = 0x00f80000;
38+
else if(old_r > 0)
39+
new_r = old_r & 0x00f80000;
40+
else
41+
new_r = 0;
42+
if(old_g > 0x00fc0000)
43+
new_g = 0x00fc0000;
44+
else if(old_g > 0)
45+
new_g = old_g & 0x00fc0000;
46+
else
47+
new_g = 0;
48+
if(old_b > 0x00f80000)
49+
new_b = 0x00f80000;
50+
else if(old_b > 0)
51+
new_b = old_b & 0x00f80000;
52+
else
53+
new_b = 0;
54+
pic[offset] = new_r;
55+
pic[offset+1] = new_g;
56+
pic[offset+2] = new_b;
57+
qe_r = old_r - new_r;
58+
qe_g = old_g - new_g;
59+
qe_b = old_b - new_b;
60+
61+
if((x+1) < width) {
62+
pic[offset+3] += (qe_r*7) >> 4;
63+
pic[offset+3+1] += (qe_g*7) >> 4;
64+
pic[offset+3+2] += (qe_b*7) >> 4;
65+
}
66+
if((y+1) < height) {
67+
offset += 3*width;
68+
if(x > 0) {
69+
pic[offset-3] += (qe_r*3) >> 4;
70+
pic[offset-3+1] += (qe_g*3) >> 4;
71+
pic[offset-3+2] += (qe_b*3) >> 4;
72+
}
73+
pic[offset] += (qe_r*5) >> 4;
74+
pic[offset+1] += (qe_g*5) >> 4;
75+
pic[offset+2] += (qe_b*5) >> 4;
76+
if((x+1) < width) {
77+
pic[offset+3] += qe_r >> 4;
78+
pic[offset+3+1] += qe_g >> 4;
79+
pic[offset+3+2] += qe_b >> 4;
80+
}
81+
}
82+
}
83+
}
84+
85+
int pixbuf_dither(unsigned short *ret, unsigned char **row_pointers, int width, int height)
86+
{
87+
int x, y;
88+
unsigned char *row;
89+
int offset;
90+
int *pic;
91+
92+
pic = malloc(width*height*3*sizeof(int));
93+
if(pic == NULL) return 0;
94+
95+
for(y=0;y<height;y++) {
96+
row = row_pointers[y];
97+
for(x=0;x<width;x++) {
98+
offset = 3*(width*y+x);
99+
pic[offset] = ((unsigned int)row[3*x]) << 16;
100+
pic[offset+1] = ((unsigned int)row[3*x+1]) << 16;
101+
pic[offset+2] = ((unsigned int)row[3*x+2]) << 16;
102+
}
103+
}
104+
105+
floyd_steinberg(pic, width, height);
106+
107+
for(y=0;y<height;y++) {
108+
for(x=0;x<width;x++) {
109+
offset = 3*(width*y+x);
110+
ret[width*y+x] = MAKERGB565N(pic[offset] >> 16,
111+
pic[offset+1] >> 16,
112+
pic[offset+2] >> 16);
113+
}
114+
}
115+
116+
free(pic);
117+
118+
return 1;
119+
}

‎src/pixbuf/dither.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Flickernoise
3+
* Copyright (C) 2011 Sebastien Bourdeauducq
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, version 3 of the License.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#ifndef __PIXBUF_DITHER_H
19+
#define __PIXBUF_DITHER_H
20+
21+
int pixbuf_dither(unsigned short *ret, unsigned char **row_pointers, int width, int height);
22+
23+
#endif /* __PIXBUF_DITHER_H */

‎src/pixbuf/loaderjpeg.c

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Flickernoise
3+
* Copyright (C) 2011 Sebastien Bourdeauducq
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, version 3 of the License.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <stdlib.h>
19+
20+
#include "pixbuf.h"
21+
#include "loaders.h"
22+
23+
struct pixbuf *pixbuf_load_jpeg(char *filename)
24+
{
25+
/* TODO */
26+
return NULL;
27+
}

‎src/pixbuf/loaderpng.c

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Flickernoise
3+
* Copyright (C) 2010, 2011 Sebastien Bourdeauducq
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, version 3 of the License.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <stdio.h>
19+
#include <stdlib.h>
20+
#include <setjmp.h>
21+
#include <png.h>
22+
#include <zlib.h>
23+
24+
#include "pixbuf.h"
25+
#include "loaders.h"
26+
27+
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
28+
#warning Floating point PNG is slow
29+
#endif
30+
31+
struct pixbuf *pixbuf_load_png(char *filename)
32+
{
33+
struct pixbuf *ret;
34+
FILE *fd;
35+
unsigned char header[8];
36+
png_structp png_ptr;
37+
png_infop info_ptr;
38+
unsigned int width, height;
39+
png_byte color_type;
40+
png_byte bit_depth;
41+
png_bytep *row_pointers;
42+
size_t rowbytes;
43+
int y;
44+
45+
ret = NULL;
46+
fd = fopen(filename, "r");
47+
if(fd == NULL) goto free0;
48+
fread(header, 1, 8, fd);
49+
if(png_sig_cmp(header, 0, 8)) goto free1;
50+
51+
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
52+
if(png_ptr == NULL) goto free1;
53+
info_ptr = png_create_info_struct(png_ptr);
54+
if(info_ptr == NULL) goto free2;
55+
56+
if(setjmp(png_jmpbuf(png_ptr))) goto free3;
57+
png_init_io(png_ptr, fd);
58+
png_set_sig_bytes(png_ptr, 8);
59+
png_read_info(png_ptr, info_ptr);
60+
61+
width = png_get_image_width(png_ptr, info_ptr);
62+
height = png_get_image_height(png_ptr, info_ptr);
63+
color_type = png_get_color_type(png_ptr, info_ptr);
64+
bit_depth = png_get_bit_depth(png_ptr, info_ptr);
65+
66+
if(color_type != PNG_COLOR_TYPE_RGB) goto free3;
67+
if(bit_depth != 8) goto free3;
68+
69+
row_pointers = calloc(sizeof(png_bytep), height);
70+
if(row_pointers == NULL) goto free3;
71+
if(setjmp(png_jmpbuf(png_ptr))) goto free4;
72+
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
73+
for(y=0;y<height;y++) {
74+
row_pointers[y] = malloc(rowbytes);
75+
if(row_pointers[y] == NULL)
76+
goto free4;
77+
}
78+
79+
png_read_image(png_ptr, row_pointers);
80+
81+
ret = pixbuf_new(width, height);
82+
if(ret == NULL) goto free4;
83+
ret->filename = strdup(filename);
84+
if(!dither(ret->pixels, row_pointers, width, height)) {
85+
pixbuf_dec_ref(ret);
86+
ret = NULL;
87+
goto free4;
88+
}
89+
90+
free4:
91+
for(y=0;y<height;y++)
92+
free(row_pointers[y]);
93+
free(row_pointers);
94+
free3:
95+
png_destroy_info_struct(png_ptr, &info_ptr);
96+
free2:
97+
png_destroy_read_struct(&png_ptr, NULL, NULL);
98+
free1:
99+
fclose(fd);
100+
free0:
101+
return ret;
102+
}

‎src/pixbuf/loaders.h

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Flickernoise
3+
* Copyright (C) 2011 Sebastien Bourdeauducq
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, version 3 of the License.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#ifndef __PIXBUF_LOADERS_H
19+
#define __PIXBUF_LOADERS_H
20+
21+
#include "pixbuf.h"
22+
23+
struct pixbuf *pixbuf_load_png(char *filename);
24+
struct pixbuf *pixbuf_load_jpeg(char *filename);
25+
26+
#endif /* __PIXBUF_LOADERS_H */

‎src/pixbuf/manager.c

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Flickernoise
3+
* Copyright (C) 2011 Sebastien Bourdeauducq
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, version 3 of the License.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <stdlib.h>
19+
#include <string.h>
20+
21+
#include "pixbuf.h"
22+
23+
static struct pixbuf *head;
24+
25+
struct pixbuf *pixbuf_new(int width, int height)
26+
{
27+
struct pixbuf *p;
28+
29+
p = malloc(sizeof(struct pixbuf)+width*height*2);
30+
if(p == NULL) return NULL;
31+
p->refcnt = 1;
32+
p->filename = NULL;
33+
p->next = head;
34+
p->width = width;
35+
p->height = height;
36+
head = p;
37+
return p;
38+
}
39+
40+
struct pixbuf *pixbuf_search(char *filename)
41+
{
42+
struct pixbuf *p;
43+
44+
p = head;
45+
while(p != NULL) {
46+
if((p->filename != NULL) && (strcmp(p->filename, filename) == 0))
47+
return p;
48+
p = p->next;
49+
}
50+
return NULL;
51+
}
52+
53+
void pixbuf_inc_ref(struct pixbuf *p)
54+
{
55+
p->refcnt++;
56+
}
57+
58+
void pixbuf_dec_ref(struct pixbuf *p)
59+
{
60+
struct pixbuf *prev;
61+
62+
p->refcnt--;
63+
if(p->refcnt == 0) {
64+
if(p == head) {
65+
head = head->next;
66+
free(p->filename);
67+
free(p);
68+
} else {
69+
prev = head;
70+
while(prev->next != p)
71+
prev = prev->next;
72+
prev->next = p->next;
73+
free(p->filename);
74+
free(p);
75+
}
76+
}
77+
}
78+
79+
struct pixbuf *pixbuf_get(char *filename)
80+
{
81+
struct pixbuf *p;
82+
83+
p = pixbuf_search(filename);
84+
if(p != NULL) {
85+
pixbuf_inc_ref(p);
86+
return p;
87+
}
88+
89+
/* try all loaders */
90+
p = pixbuf_load_png(filename);
91+
if(p != NULL) return p;
92+
p = pixbuf_load_jpeg(filename);
93+
if(p != NULL) return p;
94+
95+
/* no loader was successful */
96+
return NULL;
97+
}

‎src/pixbuf/pixbuf.h

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Flickernoise
3+
* Copyright (C) 2011 Sebastien Bourdeauducq
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, version 3 of the License.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#ifndef __PIXBUF_PIXBUF_H
19+
#define __PIXBUF_PIXBUF_H
20+
21+
struct pixbuf {
22+
int refcnt;
23+
char *filename;
24+
struct pixbuf *next;
25+
int width, height;
26+
unsigned short pixels[];
27+
};
28+
29+
struct pixbuf *pixbuf_new(int width, int height);
30+
struct pixbuf *pixbuf_search(char *filename);
31+
void pixbuf_inc_ref(struct pixbuf *p);
32+
void pixbuf_dec_ref(struct pixbuf *p);
33+
34+
struct pixbuf *pixbuf_get(char *filename);
35+
36+
#endif /* __PIXBUF_PIXBUF_H */

0 commit comments

Comments
 (0)
Please sign in to comment.