Annotation of previous/src/screenSnapShot.c, revision 1.1

1.1     ! root        1: /*
        !             2:   Hatari - screenSnapShot.c
        !             3: 
        !             4:   This file is distributed under the GNU Public License, version 2 or at
        !             5:   your option any later version. Read the file gpl.txt for details.
        !             6: 
        !             7:   Screen Snapshots.
        !             8: */
        !             9: const char ScreenSnapShot_fileid[] = "Hatari screenSnapShot.c : " __DATE__ " " __TIME__;
        !            10: 
        !            11: #include <SDL.h>
        !            12: #include <dirent.h>
        !            13: #include <string.h>
        !            14: #include "main.h"
        !            15: #include "log.h"
        !            16: #include "paths.h"
        !            17: #include "screen.h"
        !            18: #include "screenSnapShot.h"
        !            19: #include "video.h"
        !            20: /* after above that bring in config.h */
        !            21: #if HAVE_LIBPNG
        !            22: # include <png.h>
        !            23: # include <assert.h>
        !            24: # include "pixel_convert.h"                            /* inline functions */
        !            25: #endif
        !            26: 
        !            27: 
        !            28: bool bRecordingAnimation = false;           /* Recording animation? */
        !            29: static int nScreenShots = 0;                /* Number of screen shots saved */
        !            30: 
        !            31: 
        !            32: /*-----------------------------------------------------------------------*/
        !            33: /**
        !            34:  * Scan working directory to get the screenshot number
        !            35:  */
        !            36: static void ScreenSnapShot_GetNum(void)
        !            37: {
        !            38:        char dummy[5];
        !            39:        int i, num;
        !            40:        DIR *workingdir = opendir(Paths_GetWorkingDir());
        !            41:        struct dirent *file;
        !            42: 
        !            43:        nScreenShots = 0;
        !            44:        if (workingdir == NULL)  return;
        !            45: 
        !            46:        file = readdir(workingdir);
        !            47:        while (file != NULL)
        !            48:        {
        !            49:                if ( strncmp("grab", file->d_name, 4) == 0 )
        !            50:                {
        !            51:                        /* copy next 4 numbers */
        !            52:                        for (i = 0; i < 4; i++)
        !            53:                        {
        !            54:                                if (file->d_name[4+i] >= '0' && file->d_name[4+i] <= '9')
        !            55:                                        dummy[i] = file->d_name[4+i];
        !            56:                                else
        !            57:                                        break;
        !            58:                        }
        !            59: 
        !            60:                        dummy[i] = '\0'; /* null terminate */
        !            61:                        num = atoi(dummy);
        !            62:                        if (num > nScreenShots)  nScreenShots = num;
        !            63:                }
        !            64:                /* next file.. */
        !            65:                file = readdir(workingdir);
        !            66:        }
        !            67: 
        !            68:        closedir(workingdir);
        !            69: }
        !            70: 
        !            71: 
        !            72: #if HAVE_LIBPNG
        !            73: /**
        !            74:  * Save given SDL surface as PNG. Return png file size > 0 for success.
        !            75:  */
        !            76: static int ScreenSnapShot_SavePNG(SDL_Surface *surface, const char *filename)
        !            77: {
        !            78:        FILE *fp = NULL;
        !            79:        int ret;
        !            80:   
        !            81:        fp = fopen(filename, "wb");
        !            82:        if (!fp)
        !            83:                return -1;
        !            84: 
        !            85:        ret = ScreenSnapShot_SavePNG_ToFile(surface, fp, -1, -1, 0, 0, 0, 0);   /* default compression/filter and no cropping */
        !            86: 
        !            87:        fclose (fp);
        !            88:        return ret;                                     /* >0 if OK, -1 if error */
        !            89: }
        !            90: 
        !            91: 
        !            92: /**
        !            93:  * Save given SDL surface as PNG in an already opened FILE, eventually cropping some borders.
        !            94:  * Return png file size > 0 for success.
        !            95:  * This function is also used by avi_record.c to save individual frames as png images.
        !            96:  */
        !            97: int ScreenSnapShot_SavePNG_ToFile(SDL_Surface *surface, FILE *fp, int png_compression_level, int png_filter ,
        !            98:                int CropLeft , int CropRight , int CropTop , int CropBottom )
        !            99: {
        !           100:        bool do_lock;
        !           101:        int y, ret = -1;
        !           102:        int w = surface->w - CropLeft - CropRight;
        !           103:        int h = surface->h - CropTop - CropBottom;
        !           104:        Uint8 *src_ptr, *row_ptr;
        !           105:        Uint8 rowbuf[3*surface->w];
        !           106:        SDL_PixelFormat *fmt = surface->format;
        !           107:        png_colorp palette_ptr = NULL;
        !           108:        png_infop info_ptr = NULL;
        !           109:        png_structp png_ptr;
        !           110:        png_text pngtext;
        !           111:        char key[] = "Title";
        !           112:        char text[] = "Hatari screenshot";
        !           113:        long start;
        !           114:        
        !           115:        /* Create and initialize the png_struct with error handler functions. */
        !           116:        png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        !           117:        if (!png_ptr) 
        !           118:        {
        !           119:                return ret;
        !           120:        }
        !           121:        
        !           122:        /* Allocate/initialize the image information data. */
        !           123:        info_ptr = png_create_info_struct(png_ptr);
        !           124:        if (!info_ptr)
        !           125:                goto png_cleanup;
        !           126: 
        !           127:        /* libpng ugliness: Set error handling when not supplying own
        !           128:         * error handling functions in the png_create_write_struct() call.
        !           129:         */
        !           130:        if (setjmp(png_jmpbuf(png_ptr)))
        !           131:                goto png_cleanup;
        !           132: 
        !           133:        /* store current pos in fp (could be != 0 for avi recording) */
        !           134:        start = ftell ( fp );
        !           135: 
        !           136:        /* initialize the png structure */
        !           137:        png_init_io(png_ptr, fp);
        !           138: 
        !           139:        /* image data properties */
        !           140:        png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB,
        !           141:                     PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
        !           142:                     PNG_FILTER_TYPE_DEFAULT);
        !           143: 
        !           144:        if ( png_compression_level >= 0 )
        !           145:                png_set_compression_level ( png_ptr , png_compression_level );
        !           146:        if ( png_filter >= 0 )
        !           147:                png_set_filter ( png_ptr , 0 , png_filter );
        !           148:                     
        !           149:        /* image info */
        !           150:        pngtext.key = key;
        !           151:        pngtext.text = text;
        !           152:        pngtext.compression = PNG_TEXT_COMPRESSION_NONE;
        !           153: #ifdef PNG_iTXt_SUPPORTED
        !           154:        pngtext.lang = NULL;
        !           155: #endif
        !           156:        png_set_text(png_ptr, info_ptr, &pngtext, 1);
        !           157: 
        !           158:        /* write the file header information */
        !           159:        png_write_info(png_ptr, info_ptr);
        !           160: 
        !           161:        /* write surface data rows one at a time (after cropping if necessary) */
        !           162:        src_ptr = (Uint8 *)surface->pixels + CropTop * surface->pitch + CropLeft * surface->format->BytesPerPixel;
        !           163:        do_lock = SDL_MUSTLOCK(surface);
        !           164:        for (y = 0; y < h; y++) {
        !           165:                /* need to lock the surface while accessing it directly */
        !           166:                if (do_lock)
        !           167:                        SDL_LockSurface(surface);
        !           168:                switch (fmt->BytesPerPixel) {
        !           169:                case 1:
        !           170:                        /* unpack 8-bit data with RGB palette */
        !           171:                        row_ptr = rowbuf;
        !           172:                        PixelConvert_8to24Bits(row_ptr, src_ptr, w, fmt->palette->colors);
        !           173:                        break;
        !           174:                case 2:
        !           175:                        /* unpack 16-bit RGB pixels */
        !           176:                        row_ptr = rowbuf;
        !           177:                        PixelConvert_16to24Bits(row_ptr, (Uint16*)src_ptr, w, fmt);
        !           178:                        break;
        !           179:                case 3:
        !           180:                        /* PNG can handle 24-bits */
        !           181:                        row_ptr = src_ptr;
        !           182:                        break;
        !           183:                case 4:
        !           184:                        /* unpack 32-bit RGBA pixels */
        !           185:                        row_ptr = rowbuf;
        !           186:                        PixelConvert_32to24Bits(row_ptr, (Uint32*)src_ptr, w, fmt);
        !           187:                        break;
        !           188:                }
        !           189:                /* and unlock surface before syscalls */
        !           190:                if (do_lock)
        !           191:                        SDL_UnlockSurface(surface);
        !           192:                src_ptr += surface->pitch;
        !           193:                png_write_row(png_ptr, rowbuf);
        !           194:        }
        !           195: 
        !           196:        /* write the additional chuncks to the PNG file */
        !           197:        png_write_end(png_ptr, info_ptr);
        !           198: 
        !           199:        ret = ftell ( fp ) - start;                             /* size of the png image */
        !           200: png_cleanup:
        !           201:        if (palette_ptr)
        !           202:                free(palette_ptr);
        !           203:        if (png_ptr)
        !           204:                png_destroy_write_struct(&png_ptr, NULL);
        !           205:        return ret;
        !           206: }
        !           207: #endif
        !           208: 
        !           209: 
        !           210: /*-----------------------------------------------------------------------*/
        !           211: /**
        !           212:  * Save screen shot file with filename like 'grab0000.[png|bmp]',
        !           213:  * 'grab0001.[png|bmp]', etc... Whether screen shots are saved as BMP
        !           214:  * or PNG depends on Hatari configuration.
        !           215:  */
        !           216: void ScreenSnapShot_SaveScreen(void)
        !           217: {
        !           218:        char *szFileName = malloc(FILENAME_MAX);
        !           219: 
        !           220:        if (!szFileName)  return;
        !           221: 
        !           222:        ScreenSnapShot_GetNum();
        !           223:        /* Create our filename */
        !           224:        nScreenShots++;
        !           225: #if HAVE_LIBPNG
        !           226:        /* try first PNG */
        !           227:        sprintf(szFileName,"%s/grab%4.4d.png", Paths_GetWorkingDir(), nScreenShots);
        !           228:        if (ScreenSnapShot_SavePNG(sdlscrn, szFileName) > 0)
        !           229:        {
        !           230:                fprintf(stderr, "Screen dump saved to: %s\n", szFileName);
        !           231:                free(szFileName);
        !           232:                return;
        !           233:        }
        !           234: #endif
        !           235:        sprintf(szFileName,"%s/grab%4.4d.bmp", Paths_GetWorkingDir(), nScreenShots);
        !           236:        if (SDL_SaveBMP(sdlscrn, szFileName))
        !           237:                fprintf(stderr, "Screen dump failed!\n");
        !           238:        else
        !           239:                fprintf(stderr, "Screen dump saved to: %s\n", szFileName);
        !           240: 
        !           241:        free(szFileName);
        !           242: }
        !           243: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.