00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <sys/types.h>
00030 #include <errno.h>
00031
00032 #include "ppm.h"
00033
00034 static void skip_whitespace(unsigned char **data)
00035 {
00036 retry:
00037 while (**data == ' ' || **data == '\t' || **data == '\n' ||
00038 **data == '\r')
00039 (*data)++;
00040 if (**data == '#') {
00041 while (1) {
00042 if (**data == '\n' || **data == '\r')
00043 break;
00044 (*data)++;
00045 }
00046 goto retry;
00047 }
00048 }
00049
00050 static void read_num(unsigned char **data, unsigned int *num)
00051 {
00052 *num = 0;
00053 while (**data >= '0' && **data <= '9') {
00054 *num *= 10;
00055 *num += **data - '0';
00056 (*data)++;
00057 }
00058 }
00059
00060 int ppm_get_data(unsigned char *data, size_t dtsz, unsigned int *width,
00061 unsigned int *height)
00062 {
00063
00064 if (data[0] != 'P' || data[1] != '6')
00065 return EINVAL;
00066
00067 data+=2;
00068 skip_whitespace(&data);
00069 read_num(&data, width);
00070 skip_whitespace(&data);
00071 read_num(&data,height);
00072
00073 return 0;
00074 }
00075
00086 int ppm_draw(unsigned char *data, size_t datasz, unsigned int sx,
00087 unsigned int sy, unsigned int maxwidth, unsigned int maxheight,
00088 putpixel_cb_t putpixel, void *vport)
00089 {
00090 unsigned int width, height;
00091 unsigned int maxcolor;
00092 unsigned int i;
00093 unsigned int color;
00094 unsigned int coef;
00095
00096
00097 if ((data[0] != 'P') || (data[1] != '6'))
00098 return EINVAL;
00099
00100 data += 2;
00101 skip_whitespace(&data);
00102 read_num(&data, &width);
00103 skip_whitespace(&data);
00104 read_num(&data, &height);
00105 skip_whitespace(&data);
00106 read_num(&data, &maxcolor);
00107 data++;
00108
00109 if ((maxcolor == 0) || (maxcolor > 255) || (width * height > datasz))
00110 return EINVAL;
00111
00112 coef = 255 / maxcolor;
00113 if (coef * maxcolor > 255)
00114 coef -= 1;
00115
00116 for (i = 0; i < width * height; i++) {
00117
00118 if (i % width > maxwidth || i / width > maxheight) {
00119 data += 3;
00120 continue;
00121 }
00122 color = ((data[0] * coef) << 16) + ((data[1] * coef) << 8) +
00123 data[2] * coef;
00124
00125 (*putpixel)(vport, sx + (i % width), sy + (i / width), color);
00126 data += 3;
00127 }
00128
00129 return 0;
00130 }