29 #include "table/strings.h" 
   74 #if defined(_MSC_VER) || defined(__WATCOMC__) 
   87 #if defined(_MSC_VER) || defined(__WATCOMC__) 
   95   uint16 planes, bitcount;
 
   96   uint32 compression, sizeimage, xpels, ypels, clrused, clrimp;
 
  102   byte blue, green, red, reserved;
 
  104 assert_compile(
sizeof(
RgbQuad) == 4);
 
  121   switch (pixelformat) {
 
  122     case 8:  bpp = 1; 
break;
 
  124     case 32: bpp = 3; 
break;
 
  126     default: 
return false;
 
  129   FILE *f = fopen(name, 
"wb");
 
  130   if (f == NULL) 
return false;
 
  133   uint bytewidth = 
Align(w * bpp, 4); 
 
  136   uint pal_size = pixelformat == 8 ? 
sizeof(
RgbQuad) * 256 : 0;
 
  140   bfh.type = TO_LE16(
'MB');
 
  148   bih.width = TO_LE32(w);
 
  149   bih.height = TO_LE32(h);
 
  150   bih.planes = TO_LE16(1);
 
  151   bih.bitcount = TO_LE16(bpp * 8);
 
  160   if (fwrite(&bfh, 
sizeof(bfh), 1, f) != 1 || fwrite(&bih, 
sizeof(bih), 1, f) != 1) {
 
  165   if (pixelformat == 8) {
 
  168     for (uint i = 0; i < 256; i++) {
 
  169       rq[i].red   = palette[i].r;
 
  170       rq[i].green = palette[i].g;
 
  171       rq[i].blue  = palette[i].b;
 
  175     if (fwrite(rq, 
sizeof(rq), 1, f) != 1) {
 
  182   uint maxlines = 
Clamp(65536 / (w * pixelformat / 8), 16, 128); 
 
  184   uint8 *buff = MallocT<uint8>(maxlines * w * pixelformat / 8); 
 
  185   uint8 *line = 
AllocaM(uint8, bytewidth); 
 
  186   memset(line, 0, bytewidth);
 
  190     uint n = 
min(h, maxlines);
 
  194     callb(userdata, buff, h, w, n);
 
  198       if (pixelformat == 8) {
 
  200         memcpy(line, buff + n * w, w);
 
  206         for (uint i = 0; i < w; i++) {
 
  207           dst[i * 3    ] = src[i].b;
 
  208           dst[i * 3 + 1] = src[i].g;
 
  209           dst[i * 3 + 2] = src[i].r;
 
  213       if (fwrite(line, bytewidth, 1, f) != 1) {
 
  230 #if defined(WITH_PNG) 
  233 #ifdef PNG_TEXT_SUPPORTED 
  241 static void PNGAPI 
png_my_error(png_structp png_ptr, png_const_charp message)
 
  243   DEBUG(misc, 0, 
"[libpng] error: %s - %s", message, (
const char *)png_get_error_ptr(png_ptr));
 
  244   longjmp(png_jmpbuf(png_ptr), 1);
 
  247 static void PNGAPI 
png_my_warning(png_structp png_ptr, png_const_charp message)
 
  249   DEBUG(misc, 1, 
"[libpng] warning: %s - %s", message, (
const char *)png_get_error_ptr(png_ptr));
 
  270   uint bpp = pixelformat / 8;
 
  275   if (pixelformat != 8 && pixelformat != 32) 
return false;
 
  277   f = fopen(name, 
"wb");
 
  278   if (f == NULL) 
return false;
 
  282   if (png_ptr == NULL) {
 
  287   info_ptr = png_create_info_struct(png_ptr);
 
  288   if (info_ptr == NULL) {
 
  289     png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
 
  294   if (setjmp(png_jmpbuf(png_ptr))) {
 
  295     png_destroy_write_struct(&png_ptr, &info_ptr);
 
  300   png_init_io(png_ptr, f);
 
  302   png_set_filter(png_ptr, 0, PNG_FILTER_NONE);
 
  304   png_set_IHDR(png_ptr, info_ptr, w, h, 8, pixelformat == 8 ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_RGB,
 
  305     PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
 
  307 #ifdef PNG_TEXT_SUPPORTED 
  310   png_text_struct text[2];
 
  311   memset(text, 0, 
sizeof(text));
 
  312   text[0].key = 
const_cast<char *
>(
"Software");
 
  313   text[0].text = 
const_cast<char *
>(_openttd_revision);
 
  314   text[0].text_length = strlen(_openttd_revision);
 
  315   text[0].compression = PNG_TEXT_COMPRESSION_NONE;
 
  328   FOR_ALL_COMPANIES(c) {
 
  329     if (c->ai_info == NULL) {
 
  335   text[1].key = 
const_cast<char *
>(
"Description");
 
  337   text[1].text_length = p - buf;
 
  338   text[1].compression = PNG_TEXT_COMPRESSION_zTXt;
 
  339   png_set_text(png_ptr, info_ptr, text, 2);
 
  342   if (pixelformat == 8) {
 
  344     for (i = 0; i != 256; i++) {
 
  345       rq[i].red   = palette[i].r;
 
  346       rq[i].green = palette[i].g;
 
  347       rq[i].blue  = palette[i].b;
 
  350     png_set_PLTE(png_ptr, info_ptr, rq, 256);
 
  353   png_write_info(png_ptr, info_ptr);
 
  354   png_set_flush(png_ptr, 512);
 
  356   if (pixelformat == 32) {
 
  365     png_set_sBIT(png_ptr, info_ptr, &sig_bit);
 
  367 #if TTD_ENDIAN == TTD_LITTLE_ENDIAN 
  368     png_set_bgr(png_ptr);
 
  369     png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
 
  371     png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
 
  376   maxlines = 
Clamp(65536 / w, 16, 128);
 
  379   void *buff = CallocT<uint8>(w * maxlines * bpp); 
 
  384     n = 
min(h - y, maxlines);
 
  387     callb(userdata, buff, y, w, n);
 
  391     for (i = 0; i != n; i++) {
 
  392       png_write_row(png_ptr, (png_bytep)buff + i * w * bpp);
 
  396   png_write_end(png_ptr, info_ptr);
 
  397   png_destroy_write_struct(&png_ptr, &info_ptr);
 
  419   byte pal_small[16 * 3];
 
  428 assert_compile(
sizeof(
PcxHeader) == 128);
 
  450   if (pixelformat == 32) {
 
  451     DEBUG(misc, 0, 
"Can't convert a 32bpp screenshot to PCX format. Please pick another format.");
 
  454   if (pixelformat != 8 || w == 0) 
return false;
 
  456   f = fopen(name, 
"wb");
 
  457   if (f == NULL) 
return false;
 
  459   memset(&pcx, 0, 
sizeof(pcx));
 
  462   pcx.manufacturer = 10;
 
  466   pcx.xmax = TO_LE16(w - 1);
 
  467   pcx.ymax = TO_LE16(h - 1);
 
  468   pcx.hdpi = TO_LE16(320);
 
  469   pcx.vdpi = TO_LE16(320);
 
  472   pcx.cpal = TO_LE16(1);
 
  473   pcx.width = pcx.pitch = TO_LE16(w);
 
  474   pcx.height = TO_LE16(h);
 
  477   if (fwrite(&pcx, 
sizeof(pcx), 1, f) != 1) {
 
  483   maxlines = 
Clamp(65536 / w, 16, 128);
 
  486   uint8 *buff = CallocT<uint8>(w * maxlines); 
 
  491     uint n = 
min(h - y, maxlines);
 
  495     callb(userdata, buff, y, w, n);
 
  499     for (i = 0; i != n; i++) {
 
  500       const uint8 *bufp = buff + i * w;
 
  501       byte runchar = bufp[0];
 
  506       for (j = 1; j < w; j++) {
 
  509         if (ch != runchar || runcount >= 0x3f) {
 
  510           if (runcount > 1 || (runchar & 0xC0) == 0xC0) {
 
  511             if (fputc(0xC0 | runcount, f) == EOF) {
 
  517           if (fputc(runchar, f) == EOF) {
 
  529       if (runcount > 1 || (runchar & 0xC0) == 0xC0) {
 
  530         if (fputc(0xC0 | runcount, f) == EOF) {
 
  536       if (fputc(runchar, f) == EOF) {
 
  547   if (fputc(12, f) == EOF) {
 
  555   for (uint i = 0; i < 256; i++) {
 
  556     tmp[i * 3 + 0] = palette[i].r;
 
  557     tmp[i * 3 + 1] = palette[i].g;
 
  558     tmp[i * 3 + 2] = palette[i].b;
 
  560   success = fwrite(tmp, 
sizeof(tmp), 1, f) == 1;
 
  573 #if defined(WITH_PNG) 
  590   for (uint i = 0; i < 
lengthof(_screenshot_formats); i++) {
 
  607   void *src = blitter->
MoveTo(_screen.dst_ptr, 0, y);
 
  629   _screen.dst_ptr = buf;
 
  630   _screen.width = pitch;
 
  632   _screen.pitch = pitch;
 
  640   dpi.width = vp->
width;
 
  648   while (vp->
width - left != 0) {
 
  663   _screen = old_screen;
 
  674 static const char *
MakeScreenshotName(
const char *default_fn, 
const char *ext, 
bool crashlog = 
false)
 
  692   for (uint serial = 1;; serial++) {
 
  698     if (!generate) 
break; 
 
  782   byte *buf = (byte *)buffer;
 
  785     for (uint x = 
MapMaxX(); 
true; x--) {
 
  803   for (uint i = 0; i < 
lengthof(palette); i++) {