1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20 	Macintosh interface for TiMidity
21 	by T.Nogami	<t-nogami@happy.email.ne.jp>
22 
23     mac_mag.c
24     Macintosh mag loader
25 */
26 
27 /*
28  *X mag loader By Takanori Watanabe. Based on Mac mag loader.
29  */
30 
31 /*
32  * W32G Interface mag loader By Daisuke Aoki on X mag loader.
33  */
34 
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif /* HAVE_CONFIG_H */
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include "timidity.h"
42 #include "common.h"
43 #include "w32g_mag.h"
44 #include "controls.h"
45 #include "wrd.h"
46 #define BUFSIZE 512
47 static const char *MAGSIG="MAKI02  ";
48 
49 #define READSHORT(p) ((int)*(uint8*)((p)+1)*256+(int)*(uint8 *)(p))
50 #define READLONG(p) (\
51 		     (int)*(uint8*)((p)+3)*256*256*256+\
52 		     (int)*(uint8*)((p)+2)*256*256+\
53 		     (int)*(uint8*)((p)+1)*256+\
54 		     (int)*(uint8 *)(p)\
55 		     )
56 #define MAGHDRLEN 31
57 
58 void mag_delete(magdata *mg);
59 
60 static magdata *top=NULL;
61 struct magfilehdr{
62 	char machine;
63 	char mflag;
64 	char scrmode;
65 	char xorig[2];
66 	char yorig[2];
67 	char xend[2];
68 	char yend[2];
69 	char flagaoff[4];
70 	char flagboff[4];
71 	char flagbsize[4];
72 	char pxloff[4];
73 	char pxlsize[4];
74 };
75 
read_flag_1line(magdata * mh,uint8 * flag)76 static int read_flag_1line(magdata * mh,uint8 *flag )
77 {
78 	int		x, flagA,flagB,j;
79 	j=0;
80 	for( x=0; x<=mh->xend-(mh->xorig/8*8); ){
81 		flagA= mh->flagadata[mh->flagapos/8] & (0x80 >> (mh->flagapos & 0x07) );
82 		mh->flagapos++;
83 		if( flagA ){
84 			flagB= mh->flagbdata[mh->flagbpos++];
85 		}else{
86 			flagB= 0;
87 		}
88 		flag[x] ^= flagB>>4;	 x+=4;j++;
89 		flag[x] ^= flagB & 0x0F; x+=4;j++;
90 	}
91 	return j;
92 }
93 
pho_load_pixel(char * image,int width,int height,char * filename)94 int pho_load_pixel ( char *image, int width, int height, char *filename)
95 {
96 	int i,j,k,l;
97 //	static const int shift[4]={0,2,1,3};/*B,R,G,E*/
98 	static const int shift[4]={0,1,2,3};
99 	struct timidity_file *fp;
100 	char buffer[640/8];
101 
102 	if((fp=wrd_open_file(filename))==NULL)
103 		return 0;
104 
105 	for(l=0;l<4;l++){
106 		for(i=0;i<400;i++){
107 			if(tf_read(buffer,sizeof(buffer),1,fp)==0){
108 				goto close;
109 			}
110 			for(j=0;j<sizeof(buffer);j++){
111 				for(k=0;k<8;k++) {
112 					if ( j * 8 + k + i * width >= width * height ) {
113 						close_file(fp);
114 						return 0;
115 					}
116 					if ( ( buffer[j]<<k ) & 0x80 )
117 						image[ j * 8 + k + i * width ] = image[ j * 8 + k + i * width] | ( 1<< shift[l] );
118 					else
119 						image[ j * 8 + k + i * width ] = image[ j * 8 + k + i * width ] | 0;
120 				}
121 			}
122 		}
123 	}
124 close:
125 	close_file(fp);
126 	return 1;
127 }
128 
mag_load_pixel(char * image,int width,int height,magdata * mh)129 void mag_load_pixel ( char *image, int width, int height, magdata *mh )
130 {
131 	int 		x,y,i, dx,dy,pxlpos,w,j,repl;
132 	uint8 flag[800];
133 	long pixels;
134 	const int	DX[]={0,-4,-8,-16,  0,-4,  0,-4,-8,  0,-4,-8,  0,-4,-8, 0},
135 		DY[]={0, 0, 0,  0, -1,-1, -2,-2,-2, -4,-4,-4, -8,-8,-8, -16};
136 	memset(flag,0,800);
137 	mh->flagapos=mh->flagbpos=pxlpos=0;
138 	w = width;
139 	for( y=0; y<=mh->yend-mh->yorig; y++ ){
140 		repl=read_flag_1line( mh,flag );
141 		x=0;
142 		for( j=0; j<repl; j++ ){
143 			if( flag[x]==0 ){
144 				pixels=mh->pxldata[pxlpos]*256+mh->pxldata[pxlpos+1];
145 				pxlpos+=2;
146 				for( i=3; i>=0; i-- ){
147 					if(x+i < w)
148 						image [ x + i + y * width ] = pixels & 0x000F;
149 					pixels >>= 4;
150 				}
151 			} else {
152 				dx=DX[flag[x]];
153 				dy=DY[flag[x]];
154 				for(i=0;i<4;i++) {
155 					if(x+i < w)
156 						image [ x + i + y * width ] = image [ x+dx+i + (y+dy) * width ];
157 				}
158 			}
159 			x+=4;
160 		}
161 	}
162 }
163 
mag_deletetab(void)164 void mag_deletetab(void)
165 {
166 	if(top!=NULL){
167 		mag_delete(top);
168 	}
169 	top=NULL;
170 }
171 
mag_delete(magdata * mg)172 void mag_delete(magdata *mg){
173 	if(mg->next!=NULL)
174 		mag_delete(mg->next);
175 	free(mg->filename);
176 	free(mg->flagadata);
177 	free(mg->flagbdata);
178 	free(mg->pxldata);
179 	free(mg);
180 }
181 
mag_search(char * filename)182 magdata *mag_search (char *filename )
183 {
184 	magdata *m;
185 	for(m=top;m!=NULL;m=m->next)
186 		if(strcmp(filename,m->filename)==0)
187 			return m;
188 		return NULL;
189 }
190 
mag_create(char * file)191 magdata *mag_create ( char *file )
192 {
193 	struct timidity_file *fp=NULL;
194 	int i;
195 	uint8 buffer[BUFSIZE];
196 	int *pal;
197 	magdata mg,*res;
198 	struct magfilehdr mfh;
199 	int len,c,header_pos;
200 	char *flaga=NULL,*flagb=NULL,*pixels=NULL;
201 	if((res=mag_search(file))){
202 		return res;
203 	}
204 	mg.filename=safe_malloc(strlen(file)+2);
205 	strcpy(mg.filename,file);
206 	fp=wrd_open_file(file);
207 	if(fp==NULL){
208 		goto error;
209 	}
210 	header_pos=0;
211 	while((c=tf_getc(fp))!=0){
212 		len=strlen(MAGSIG);
213 		if(header_pos<len)
214 			buffer[header_pos]=c;
215 		else if(header_pos==len){
216 			if(memcmp(MAGSIG,buffer,len)!=0){
217 				ctl->cmsg(CMSG_INFO,VERB_VERBOSE,"BAD SIGNATURE\n");
218 				goto error;
219 			}
220 		}
221 		header_pos++;
222 	}
223 	/*READ FHDR*/
224 	{
225 		if(tf_read(&mfh,sizeof(mfh),1,fp)==0){
226 			fprintf(stderr,"FOO!\n");
227 			goto error;
228 		}
229 		mg.machine=mfh.machine;
230 		mg.mflag=mfh.mflag;
231 		mg.scrmode=mfh.scrmode;
232 		mg.xorig=READSHORT(mfh.xorig);
233 		mg.yorig=READSHORT(mfh.yorig);
234 		mg.xend=READSHORT(mfh.xend);
235 		mg.yend=READSHORT(mfh.yend);
236 		mg.flagaoff=READLONG(mfh.flagaoff);
237 		mg.flagboff=READLONG(mfh.flagboff);
238 		mg.flagbsize=READLONG(mfh.flagbsize);
239 		mg.pxloff=READLONG(mfh.pxloff);
240 		mg.pxlsize=READLONG(mfh.pxlsize);
241 	}
242 	/*READ PALLET*/
243 //	pal=mg.pal+1;
244 	pal=mg.pal;
245 	for(i=0;i<PALSIZE;i++){
246 		if(tf_read(buffer,1,3,fp)<3){
247 			goto error;
248 		}
249 		pal[i] = 0;
250 		pal[i] |=  ( (int)( buffer[0] / 16 ) & 0x0F ) << 8;
251 		pal[i] |=  ( (int)( buffer[1] / 16 ) & 0x0F ) << 4;
252 		pal[i] |=  ( (int)( buffer[2] / 16 ) & 0x0F ) << 0;
253 	}
254 
255 	{
256 		int flaga_size,res;
257 		flaga_size=mg.flagboff-mg.flagaoff;
258 		if(tf_seek(fp,mg.flagaoff+header_pos,SEEK_SET)==-1)
259 			goto error;
260 		flaga=safe_malloc(flaga_size+100);
261 		if((res=tf_read(flaga,1,flaga_size,fp))<flaga_size)
262 			goto error;
263 		mg.flagadata=flaga;
264 	}
265 	{
266 		flagb=safe_malloc(mg.flagbsize+100);
267 		if(tf_seek(fp,mg.flagboff+header_pos,SEEK_SET)==-1)
268 			goto error;
269 		if(tf_read(flagb,1,mg.flagbsize,fp)<mg.flagbsize)
270 			goto error;
271 		mg.flagbdata=flagb;
272 	}
273 	{
274 		pixels=safe_malloc(mg.pxlsize+100);
275 		if(tf_seek(fp,mg.pxloff+header_pos,SEEK_SET)==-1)
276 			goto error;
277 		if(tf_read(pixels,1,mg.pxlsize,fp)<mg.pxlsize)
278 			goto error;
279 		mg.pxldata=pixels;
280 	}
281 	res=safe_malloc(sizeof(magdata));
282 
283 	*res=mg;
284 	close_file(fp);
285 	res->next=top;
286 	top=res;
287 	return res;
288 error:
289 	if(fp!=NULL)
290 	{
291 		close_file(fp);
292 		ctl->cmsg(CMSG_INFO,VERB_VERBOSE,"Mag error: %s\n", file);
293 	}
294 	free(mg.filename);
295 	if(flaga != NULL)
296 		free(flaga);
297 	if(flagb != NULL)
298 		free(flagb);
299 	if(pixels != NULL)
300 		free(pixels);
301 	return NULL;
302 }
303