-
Notifications
You must be signed in to change notification settings - Fork 0
/
xvpictoppm.c
169 lines (122 loc) · 3.39 KB
/
xvpictoppm.c
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
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
* xvpictoppm.c - reads XV 'thumbnail' files from stdin, writes standard PPM
* files to stdout
*/
/*
* THUMBNAIL FILE FORMAT:
*
* <magic number 'P7 332' >
* <comment identifying version of XV that wrote this file>
* <comment identifying type & size of the full-size image>
* <OPTIONAL comment identifying this as a BUILT-IN icon, in which case
* there is no width,height,maxval info, nor any 8-bit data>
* <comment signifying end of comments>
* <width, height, and maxval of this file >
* <raw binary 8-bit data, in 3/3/2 Truecolor format>
*
* Example:
* P7 332
* #XVVERSION:Version 2.28 Rev: 9/26/92
* #IMGINFO:512x440 Color JPEG
* #END_OF_COMMENTS
* 48 40 255
* <binary data>
*
* alternately:
* P7 332
* #XVVERSION:Version 2.28 Rev: 9/26/92
* #BUILTIN:UNKNOWN
* #IMGINFO:
* #END_OF_COMMENTS
*/
#include "xv.h"
#include "copyright.h"
/*************** Function Declarations *************/
int main PARM((int, char **));
static void errexit PARM((void));
static byte *loadThumbFile PARM((int *, int *));
static void writePPM PARM((byte *, int, int));
/****************************/
int main(argc, argv)
int argc;
char **argv;
{
byte *pic;
int w,h;
pic = loadThumbFile(&w, &h);
writePPM(pic, w, h);
return 0;
}
/****************************/
static void errexit()
{
perror("Unable to convert thumbnail file");
exit(-1);
}
/****************************/
static byte *loadThumbFile(wptr, hptr)
int *wptr, *hptr;
{
/* read a thumbnail file from stdin */
FILE *fp;
byte *icon8, *pic24, *ip, *pp;
char buf[256];
int i, builtin, w, h, mv;
fp = stdin;
builtin = 0;
if (!fgets(buf, 256, fp)) errexit();
if (strncmp(buf, "P7 332", (size_t) 6)) errexit();
/* read comments until we see '#END_OF_COMMENTS', or hit EOF */
while (1) {
if (!fgets(buf, 256, fp)) errexit();
if (!strncmp(buf, "#END_OF_COMMENTS", (size_t) 16)) break;
else if (!strncmp(buf, "#BUILTIN:", (size_t) 9)) {
builtin = 1;
fprintf(stderr,"Built-In icon: no image to convert!\n");
exit(1);
}
}
/* read width, height, maxval */
if (!fgets(buf, 256, fp) || sscanf(buf, "%d %d %d", &w, &h, &mv) != 3)
errexit();
if (w<1 || h<1 || mv != 255) {
fprintf(stderr,"Bogus thumbnail file!\n");
exit(1);
}
/* read binary data */
icon8 = (byte *) malloc((size_t) w * h);
if (!icon8) errexit();
i = fread(icon8, (size_t) 1, (size_t) w*h, fp);
if (i != w*h) errexit();
/* make 24-bit version of icon */
pic24 = (byte *) malloc((size_t) w * h * 3);
if (!pic24) errexit();
/* convert icon from 332 to 24-bit image */
for (i=0, ip=icon8, pp=pic24; i<w*h; i++, ip++, pp+=3) {
pp[0] = ( ((int) ((*ip >> 5) & 0x07)) * 255) / 7;
pp[1] = ( ((int) ((*ip >> 2) & 0x07)) * 255) / 7;
pp[2] = ( ((int) ((*ip >> 0) & 0x03)) * 255) / 3;
}
free(icon8);
*wptr = w; *hptr = h;
return pic24;
}
/*******************************************/
static void writePPM(pic, w, h)
byte *pic;
int w,h;
{
FILE *fp;
byte *pix;
int i,j,len;
fp = stdout;
fprintf(fp,"P6\n");
fprintf(fp,"%d %d %d\n", w, h, 255);
if (ferror(fp)) errexit();
for (i=0, pix=pic, len=0; i<h; i++) {
for (j=0; j<w; j++, pix+=3) {
putc(pix[0],fp); putc(pix[1],fp); putc(pix[2],fp);
}
}
if (ferror(fp)) errexit();
}