-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtif2basic.c
More file actions
149 lines (116 loc) · 4.84 KB
/
tif2basic.c
File metadata and controls
149 lines (116 loc) · 4.84 KB
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
#include <stdio.h>
int imageWidth = 280;
int imageHeight = 192;
int main(int argc, char *argv[]) {
char *filename = argv[1];
unsigned char imageData[imageWidth * imageHeight];
if (!filename) {
printf("TIF to Apple ][ BASIC\nUsage: ./tif2basic image.tif\n\nPlease have your image cropped to 280x192px, indexed color mode (2 colors -- black and white), and saved as a TIF with no compression, pixels ordered per-channel, and a byte order of Macintosh.\n");
return 1;
}
// Grab the input file
FILE *fp;
fp = fopen(filename, "rb");
// Our first check should be the filesize. If it's a perfect size for
// our width * height, then we can assume this is already the perfect
// format, and rip raw byte values.
unsigned int filesize;
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (filesize == imageWidth * imageHeight) {
// Must be the raw pixel data, so let's pull the bytes out into the
// imageData array.
fread(imageData, sizeof(imageData), 1, fp);
} else {
// This could be a TIF file. Let's check...
unsigned char fileSig[4]; // Used to check if input is a TIF
fread(fileSig, sizeof(fileSig), 1, fp); // read 10 bytes to our buffer
// Check if this is a TIF image in little-endian format
unsigned char tifSig[4] = {0x4D, 0x4D, 0x00, 0x2A};
unsigned int fileSigMatch = 1; // Will spoil if something doesn't match
for (int i = 0; i < sizeof(tifSig); i++) {
if (tifSig[i] != fileSig[i]) {
fileSigMatch = 0;
}
}
if (!fileSigMatch) {
printf("Please only use TIF files with this program.\n");
return 1;
}
// If this runs, then the above checks out. Let's read in the file
// data.
unsigned char imageBuffer[100000]; // Enough to hold everything
fread(imageBuffer, sizeof(imageBuffer), 1, fp);
// Now let's search for the 'end of data' string -- I've noticed it
// is always 00 03 A0 when exporting from Photoshop CS4, so I'm just
// going to assume that.
unsigned int iEndOfImageData;
unsigned char testbyte, nextbyte;
for (unsigned int byteNum = 0; byteNum < (sizeof(imageBuffer) - 1); byteNum++) {
testbyte = imageBuffer[byteNum];
nextbyte = imageBuffer[byteNum + 1];
if (testbyte == 0x03 && nextbyte == 0xA0) {
// Found it
iEndOfImageData = byteNum - 2; // One for 0x00, one more for data
break;
}
}
// Time to get the image data. We know the index of the last byte of
// image data, so let's start there and work backwards.
for (unsigned int byteNum = 0; byteNum < sizeof(imageData); byteNum++) {
imageData[sizeof(imageData) - 1 - byteNum] = imageBuffer[iEndOfImageData - byteNum];
}
}
// Now that we have the image data, let's make the BASIC program!
int basicLineNumber = 100;
// Print the image interpreter routine
// This is originally written by Brian Broker, found on
// http://www.calormen.com/jsbasic/.
printf("10\tHGR2 : HCOLOR= 1\n20\tFOR Y = 0 TO 191\n30\t FOR X = 0 TO 279 STEP 16\n40\t READ N\n50\t FOR I = 0 TO 15\n60\t N = N/2 : IF N <> INT(N) THEN HPLOT X+I, Y : N = INT(N)\n70\t NEXT\n80\t NEXT\n90\tNEXT\n");
for (int lineNum = 0; lineNum < 192; lineNum++) {
int linePixelStart = lineNum * imageWidth;
int blockNum;
int block[18];
// We should set up a pixel threshold, to distinguish between Apple
// II white and black pixels. Here, I'm setting the threshold to
// 0x00 so anything that isn't 'black' is considered 'white'.
unsigned char pixelThreshold = 0x01;
unsigned char pixelValue;
// Get the first 17 blocks (of 16 pixels)
for (blockNum = 0; blockNum < 17; blockNum++) {
float blockAsNumber = 0;
for (int pixelNum = 15; pixelNum >= 0; pixelNum--) {
int imagePixelNum = linePixelStart + (16 * blockNum) + pixelNum;
pixelValue = imageData[imagePixelNum];
if (pixelThreshold <= pixelValue) {
blockAsNumber += 0.5;
}
blockAsNumber *= 2;
}
block[blockNum] = (int)blockAsNumber;
}
// Get the 18th block (of 8 pixels)
float blockAsNumber = 0;
for (int pixelNum = 7; pixelNum >= 0; pixelNum--) {
int imagePixelNum = linePixelStart + (16 * blockNum) + pixelNum;
pixelValue = imageData[imagePixelNum];
if (pixelThreshold <= pixelValue) {
blockAsNumber += 0.5;
}
blockAsNumber *= 2;
}
block[blockNum] = (int)blockAsNumber;
// Now that we have the block, write it to screen
printf("%d\tDATA ", basicLineNumber);
for (int i = 0; i < 18; i++) {
if (17 != i) {
printf("%d,", block[i]);
} else {
printf("%d\n", block[i]);
}
}
basicLineNumber += 10;
}
return 0;
}