int ColorModel::allocate() { if (alloc_grays() < 0 || alloc_colors() < 0) { free_colors(); return (-1); } return (0); }
/************************************************************* ... *************************************************************/ static void alloc_standard_colors(void) { XColor mycolors[COLOR_STD_LAST]; int i; for(i=0; i<COLOR_STD_LAST; i++) { mycolors[i].red = colors_standard_rgb[i].r << 8; mycolors[i].green = colors_standard_rgb[i].g << 8; mycolors[i].blue = colors_standard_rgb[i].b << 8; } alloc_colors(mycolors, COLOR_STD_LAST); for (i = 0; i < COLOR_STD_LAST; i++) { colors_standard[i] = mycolors[i].pixel; } }
/*************************************************************************** ... ***************************************************************************/ struct sprite *load_gfxfile(const char *filename) { png_structp pngp; png_infop infop; png_int_32 width, height, x, y; FILE *fp; int npalette, ntrans; png_colorp palette; png_bytep trans; png_bytep buf, pb; png_uint_32 stride; unsigned long *pcolorarray; bool *ptransarray; struct sprite *mysprite; XImage *xi; int has_mask; png_byte color_type; png_byte alpha; bool pixel, reported; fp = fc_fopen(filename, "rb"); if (!fp) { log_fatal("Failed reading PNG file: \"%s\"", filename); exit(EXIT_FAILURE); } pngp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!pngp) { log_fatal("Failed creating PNG struct"); exit(EXIT_FAILURE); } infop = png_create_info_struct(pngp); if (!infop) { log_fatal("Failed creating PNG struct"); exit(EXIT_FAILURE); } if (setjmp(png_jmpbuf(pngp))) { log_fatal("Failed while reading PNG file: \"%s\"", filename); exit(EXIT_FAILURE); } png_init_io(pngp, fp); png_set_strip_16(pngp); png_set_packing(pngp); png_read_info(pngp, infop); width = png_get_image_width(pngp, infop); height = png_get_image_height(pngp, infop); color_type = png_get_color_type(pngp, infop); if (color_type == PNG_COLOR_TYPE_PALETTE) { if (png_get_PLTE(pngp, infop, &palette, &npalette)) { int i; XColor *mycolors; pcolorarray = fc_malloc(npalette * sizeof(*pcolorarray)); mycolors = fc_malloc(npalette * sizeof(*mycolors)); for (i = 0; i < npalette; i++) { mycolors[i].red = palette[i].red << 8; mycolors[i].green = palette[i].green << 8; mycolors[i].blue = palette[i].blue << 8; } alloc_colors(mycolors, npalette); for (i = 0; i < npalette; i++) { pcolorarray[i] = mycolors[i].pixel; } free(mycolors); } else { log_fatal("PNG file has no palette: \"%s\"", filename); exit(EXIT_FAILURE); } has_mask = png_get_tRNS(pngp, infop, &trans, &ntrans, NULL); if (has_mask) { int i; ptransarray = fc_calloc(npalette, sizeof(*ptransarray)); reported = FALSE; for (i = 0; i < ntrans; i++) { if (trans[i] < npalette) { ptransarray[trans[i]] = TRUE; } else if (!reported) { log_verbose("PNG: Transparent array entry is out of palette: " "\"%s\"", filename); reported = TRUE; } } } else { ptransarray = NULL; } } else { pcolorarray = NULL; ptransarray = NULL; npalette = 0; if ((color_type == PNG_COLOR_TYPE_RGB_ALPHA) || (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) { has_mask = 1; } else { has_mask = 0; } ntrans = 0; } png_read_update_info(pngp, infop); { png_bytep *row_pointers; stride = png_get_rowbytes(pngp, infop); buf = fc_malloc(stride * height); row_pointers = fc_malloc(height * sizeof(png_bytep)); for (y = 0, pb = buf; y < height; y++, pb += stride) { row_pointers[y] = pb; } png_read_image(pngp, row_pointers); png_read_end(pngp, infop); fclose(fp); free(row_pointers); if (infop != NULL) { png_destroy_read_struct(&pngp, &infop, (png_infopp)NULL); } else { log_error("PNG info struct is NULL (non-fatal): \"%s\"", filename); png_destroy_read_struct(&pngp, (png_infopp)NULL, (png_infopp)NULL); } } mysprite = fc_malloc(sizeof(*mysprite)); xi = XCreateImage(display, DefaultVisual(display, screen_number), display_depth, ZPixmap, 0, NULL, width, height, 32, 0); xi->data = fc_calloc(xi->bytes_per_line * xi->height, 1); pb = buf; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { if (pcolorarray) { XPutPixel(xi, x, y, pcolorarray[pb[x]]); } else { if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { XPutPixel(xi, x, y, (pb[2 * x] << 16) + (pb[2 * x] << 8) + pb[2 * x]); } else { if (has_mask) { XPutPixel(xi, x, y, (pb[4 * x] << 16) + (pb[4 * x + 1] << 8) + pb[4 * x + 2]); } else { XPutPixel(xi, x, y, (pb[3 * x] << 16) + (pb[3 * x + 1] << 8) + pb[3 * x + 2]); } } } } pb += stride; } mysprite->pixmap = image2pixmap(xi); XDestroyImage(xi); if (has_mask) { XImage *xm; xm = XCreateImage(display, DefaultVisual(display, screen_number), 1, XYBitmap, 0, NULL, width, height, 8, 0); xm->data = fc_calloc(xm->bytes_per_line * xm->height, 1); pb = buf; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { if (ptransarray) { XPutPixel(xm, x, y, !ptransarray[pb[x]]); } else { if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { alpha = pb[2 * x + 1]; } else { alpha = pb[4 * x + 3]; } if (alpha > 204) { pixel = FALSE; } else if (alpha > 153) { if ((y + x * 2) % 4 == 0) { pixel = TRUE; } else { pixel = FALSE; } } else if (alpha > 102) { if ((y + x) % 2 == 0) { pixel = TRUE; } else { pixel = FALSE; } } else if (alpha > 51) { if ((y + x * 2) % 4 == 0) { pixel = FALSE; } else { pixel = TRUE; } } else { pixel = TRUE; } XPutPixel(xm, x, y, !pixel); } } pb += stride; } mysprite->mask = image2pixmap(xm); XDestroyImage(xm); } mysprite->has_mask = has_mask; mysprite->width = width; mysprite->height = height; mysprite->pcolorarray = pcolorarray; mysprite->ncols = npalette; if (ptransarray) { free(ptransarray); } free(buf); return mysprite; }