chiark / gitweb /
WIP island determination; can recognise a pixmap!
[ypp-sc-tools.main.git] / pctb / rgbimage.c
1 /*
2  * Handling of colour (RGB) images
3  */
4 /*
5  *  This is part of ypp-sc-tools, a set of third-party tools for assisting
6  *  players of Yohoho Puzzle Pirates.
7  * 
8  *  Copyright (C) 2009 Ian Jackson <ijackson@chiark.greenend.org.uk>
9  * 
10  *  This program is free software: you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation, either version 3 of the License, or
13  *  (at your option) any later version.
14  * 
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  * 
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  * 
23  *  Yohoho and Puzzle Pirates are probably trademarks of Three Rings and
24  *  are used without permission.  This program is not endorsed or
25  *  sponsored by Three Rings.
26  */
27
28 #include "convert.h"
29
30 /*
31  *
32  *
33  * widgets.txt
34  * format
35  *
36  *  <magic>
37  *
38  *  <context>
39  *  <string>
40  *  ppmnoraw depth 8
41  *
42  *  <context>
43  *  <string>
44  *  ppmnoraw depth 8
45  *  .
46  *
47  */
48
49 #include "convert.h"
50
51 static int identify(const RgbImage *base, Rect portion,
52                     char result[MAXIMGIDENT], const char *what) {
53   sysassert( dbfile_open("pixmaps.txt") );
54
55 #define FGETSLINE (dbfile_getsline(result,MAXIMGIDENT,__FILE__,__LINE__))
56
57   FGETSLINE;
58   dbassert(!strcmp(result,"# ypp-sc-tools pctb pixmaps v1"));
59   
60   void *row= 0;
61   size_t rowa= 0;
62   
63   for (;;) {
64     FGETSLINE;
65     if (!result[0] || result[0]=='#') continue;
66     if (!strcmp(result,".")) break;
67
68     char magic[10];
69     dbfile_getsline(magic,sizeof(magic),__FILE__,__LINE__);
70
71     dbassert(!strcmp(magic,"P3"));
72     int w,h,maxval;
73     dbassert( dbfile_scanf("%d %d %d",&w,&h,&maxval) == 3);
74     dbassert(w>0); dbassert(h>0); dbassert(maxval==255);
75
76     if (rowa < w) {
77       rowa= w;
78       row= mrealloc(row, rowa*3);
79     }
80     int diff= w != RECT_W(portion) || h != RECT_H(portion);
81
82     int x,y,i;
83     for (y=0; y<h; y++) {
84       for (x=0; x<w; x++) {
85         for (i=0; i<3; i++) {
86           int c;
87           dbassert( dbfile_scanf("%d",&c) == 1);
88           dbassert(c>=0 && c<=255);
89           diff |= (c != RI_PIXEL(base, portion.tl.x + x, portion.tl.y + y)[i]);
90         }
91       }
92     }
93     if (!diff) {
94       progress_log("Identified %s image: %s.",what,result);
95       goto found;
96     }
97   }
98   result[0]= 0;
99
100 found:
101   dbfile_close();
102   return !!result[0];
103 }
104  
105 void identify_rgbimage(const RgbImage *base, Rect portion,
106                        char result[MAXIMGIDENT], const char *what) {
107   int ok= identify(base, portion, result, what);
108   if (ok) return;
109
110   if (DEBUGP(pixmap)) {
111     int x,y,i;
112     fprintf(stderr,"P3\n%d %d\n255\n", RECT_W(portion), RECT_H(portion));
113     for (y=portion.tl.y; y<=portion.br.y; y++) {
114       for (x=portion.tl.x; x<=portion.br.x; x++) {
115         putc(' ',stderr);
116         for (i=0; i<3; i++)
117           fprintf(stderr," %3d", RI_PIXEL(base,x,y)[i]);
118       }
119       putc('\n',stderr);
120     }
121   }
122   fatal("Unrecognised pixmap for %s.", what);
123 }
124
125 RgbImage *alloc_rgb_image(int w, int h) {
126   RgbImage *ri;
127   ri= mmalloc(sizeof(*ri) + w*h*3);
128   ri->w= w;
129   ri->h= h;
130   return ri;
131 }