void CGraphics_OpenGL::ScreenShotThread(void *pUser) { ScreenshotThreadStruct *pScreenshotData = (ScreenshotThreadStruct *)pUser; unsigned char *pTempRow = pScreenshotData->m_pPixelData+pScreenshotData->m_w*pScreenshotData->m_h*3; // flip the pixel because opengl works from bottom left corner for(int y = 0; y < pScreenshotData->m_h/2; y++) { mem_copy(pTempRow, pScreenshotData->m_pPixelData+y*pScreenshotData->m_w*3, pScreenshotData->m_w*3); mem_copy(pScreenshotData->m_pPixelData+y*pScreenshotData->m_w*3, pScreenshotData->m_pPixelData+(pScreenshotData->m_h-y-1)*pScreenshotData->m_w*3, pScreenshotData->m_w*3); mem_copy(pScreenshotData->m_pPixelData+(pScreenshotData->m_h-y-1)*pScreenshotData->m_w*3, pTempRow,pScreenshotData->m_w*3); } // find filename { char aWholePath[1024]; png_t Png; // ignore_convention IOHANDLE File = pScreenshotData->m_pSelf->m_pStorage->OpenFile(pScreenshotData->m_aFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE, aWholePath, sizeof(aWholePath)); if(File) io_close(File); // save png dbg_msg("client", "saved screenshot to '%s'", aWholePath); png_open_file_write(&Png, aWholePath); // ignore_convention png_set_data(&Png, pScreenshotData->m_w, pScreenshotData->m_h, 8, PNG_TRUECOLOR, (unsigned char *)pScreenshotData->m_pPixelData); // ignore_convention png_close_file(&Png); // ignore_convention } mem_free(pScreenshotData->m_pPixelData); delete pScreenshotData; }
void CGraphics_Threaded::ScreenshotDirect(const char *pFilename) { // add swap command CImageInfo Image; mem_zero(&Image, sizeof(Image)); CCommandBuffer::SCommand_Screenshot Cmd; Cmd.m_pImage = &Image; m_pCommandBuffer->AddCommand(Cmd); // kick the buffer and wait for the result KickCommandBuffer(); WaitForIdle(); if(Image.m_pData) { // find filename char aWholePath[1024]; png_t Png; // ignore_convention IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE, aWholePath, sizeof(aWholePath)); if(File) io_close(File); // save png char aBuf[256]; str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath); m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); png_open_file_write(&Png, aWholePath); // ignore_convention png_set_data(&Png, Image.m_Width, Image.m_Height, 8, PNG_TRUECOLOR, (unsigned char *)Image.m_pData); // ignore_convention png_close_file(&Png); // ignore_convention mem_free(Image.m_pData); } }
int FixFile(const char *pFileName) { png_t Png; CPixel *pBuffer[2] = {0,0}; png_init(0, 0); png_open_file(&Png, pFileName); if(Png.color_type != PNG_TRUECOLOR_ALPHA) { dbg_msg("tileset_borderadd", "%s: not an RGBA image", pFileName); return 1; } int w = Png.width; int h = Png.height; pBuffer[0] = (CPixel*)mem_alloc(w*h*sizeof(CPixel), 1); pBuffer[1] = (CPixel*)mem_alloc((w+16*4)*(h+16*4)*sizeof(CPixel), 1); png_get_data(&Png, (unsigned char *)pBuffer[0]); png_close_file(&Png); TilesetBorderadd(w, h, pBuffer[0], pBuffer[1]); // save here png_open_file_write(&Png, pFileName); png_set_data(&Png, w + 16 * 4, h + 16 * 4, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)pBuffer[1]); png_close_file(&Png); return 0; }
int main(int argc, const char **argv) { if(argc != 2) { printf("wrong arguments, there has to be one and only one and this is the mapfile to extract the images from.\n"); return -1; } IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); CDataFileReader DataFile; if(!pStorage) { printf("Cannot get storage\n"); return -1; } if(!DataFile.Open(pStorage, argv[1], IStorage::TYPE_ALL)) { printf("Cannot read %s\n", argv[1]); return -1; } printf("Loading %s\n", argv[1]); png_init(0, 0); // load images int start, num; DataFile.GetType(MAPITEMTYPE_IMAGE, &start, &num); for(int i = 0; i < num; i++) { CMapItemImage *pImg = (CMapItemImage *)DataFile.GetItem(start+i, 0, 0); char *pName = (char *)DataFile.GetData(pImg->m_ImageName); if(pImg->m_External) { printf("skipping external %s\n", pName); } else { printf("writing %s.png\n", pName); void *pData = DataFile.GetData(pImg->m_ImageData); char buf[255]; #if defined(CONF_FAMILY_WINDOWS) _snprintf(buf, sizeof(buf), "%s.png", pName); #else snprintf(buf, sizeof(buf), "%s.png", pName); #endif png_t png; png_open_file_write(&png, buf); png_set_data(&png, pImg->m_Width, pImg->m_Height, 8, PNG_TRUECOLOR_ALPHA, (unsigned char*) pData); png_close_file(&png); DataFile.UnloadData(pImg->m_ImageData); } } DataFile.Close(); return 0; }
void CGraphics_OpenGL::ScreenshotDirect(const char *pFilename) { // fetch image data int y; int w = m_ScreenWidth; int h = m_ScreenHeight; unsigned char *pPixelData = (unsigned char *)mem_alloc(w*(h+1)*3, 1); unsigned char *pTempRow = pPixelData+w*h*3; GLint Alignment; glGetIntegerv(GL_PACK_ALIGNMENT, &Alignment); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0,0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pPixelData); glPixelStorei(GL_PACK_ALIGNMENT, Alignment); if (g_Config.m_ClScreenShotThread) { ScreenshotThreadStruct *ScreenshotData = new ScreenshotThreadStruct(); str_copy(ScreenshotData->m_aFilename, pFilename, sizeof(ScreenshotData->m_aFilename)); ScreenshotData->m_h = h; ScreenshotData->m_w = w; ScreenshotData->m_pPixelData = pPixelData; ScreenshotData->m_pSelf = this; void *t = thread_create(ScreenShotThread, ScreenshotData); thread_detach(t); } else { // flip the pixel because opengl works from bottom left corner for(y = 0; y < h/2; y++) { mem_copy(pTempRow, pPixelData+y*w*3, w*3); mem_copy(pPixelData+y*w*3, pPixelData+(h-y-1)*w*3, w*3); mem_copy(pPixelData+(h-y-1)*w*3, pTempRow,w*3); } // find filename { char aWholePath[1024]; png_t Png; // ignore_convention IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE, aWholePath, sizeof(aWholePath)); if(File) io_close(File); // save png char aBuf[256]; str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath); m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); png_open_file_write(&Png, aWholePath); // ignore_convention png_set_data(&Png, w, h, 8, PNG_TRUECOLOR, (unsigned char *)pPixelData); // ignore_convention png_close_file(&Png); // ignore_convention } // clean up mem_free(pPixelData); } }
void saveFrameBuffer() { unsigned char* pixBuffer = (unsigned char*)malloc(window_width*window_height*4); glReadPixels(0,0, window_width, window_height, GL_RGB, GL_UNSIGNED_BYTE, pixBuffer); char filename[50]; sprintf(filename, "%d-%d.png",baseNum, ++saveNumber); // initialize png_t pngStruct; png_init(0, 0); if(png_open_file_write(&pngStruct, filename)==0) if(png_set_data(&pngStruct, window_width, window_height, 8, PNG_TRUECOLOR, pixBuffer)==0) if(png_close_file(&pngStruct)==0) printf("Saved frame buffer.\n"); }
static int write_png_file(char* filename, int width, int height, unsigned char *buffer) { png_t png; FILE * fp = fopen(filename, "wb"); if (fp == NULL) { fprintf(stderr, "Could not open file %s for writing\n", filename); return 1; } fclose(fp); png_init(0,0); png_open_file_write(&png, filename); png_set_data(&png, width, height, 8, PNG_TRUECOLOR, buffer); png_close_file(&png); return 0; }
void CGraphics_OpenGL::ScreenshotDirect(const char *pFilename) { // fetch image data int y; int w = m_ScreenWidth; int h = m_ScreenHeight; unsigned char *pPixelData = (unsigned char *)mem_alloc(w*(h+1)*3, 1); unsigned char *pTempRow = pPixelData+w*h*3; GLint Alignment; glGetIntegerv(GL_PACK_ALIGNMENT, &Alignment); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0,0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pPixelData); glPixelStorei(GL_PACK_ALIGNMENT, Alignment); // flip the pixel because opengl works from bottom left corner for(y = 0; y < h/2; y++) { mem_copy(pTempRow, pPixelData+y*w*3, w*3); mem_copy(pPixelData+y*w*3, pPixelData+(h-y-1)*w*3, w*3); mem_copy(pPixelData+(h-y-1)*w*3, pTempRow,w*3); } // find filename { char aWholePath[1024]; png_t Png; // ignore_convention IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_WRITE, aWholePath, sizeof(aWholePath)); if(File) io_close(File); // save png dbg_msg("client", "saved screenshot to '%s'", aWholePath); png_open_file_write(&Png, aWholePath); // ignore_convention png_set_data(&Png, w, h, 8, PNG_TRUECOLOR, (unsigned char *)pPixelData); // ignore_convention png_close_file(&Png); // ignore_convention } // clean up mem_free(pPixelData); }
int png_save_file(png_file* file, const char* path) { int r; png_t ps; r = png_open_file_write(&ps, path); png_write_error(r); if( r >= PNG_NO_ERROR ) { // ToDo: User selectable bitrate for output r = png_set_data(&ps, file->png_obj.width, file->png_obj.height, 8, file->png_obj.color_type, file->data); png_write_error(r); if( r >= PNG_NO_ERROR ) { // Close r = png_close_file(&ps); png_write_error(r); } } return r; }
int DilateFile(const char *pFileName) { png_t Png; CPixel *pBuffer[3] = {0,0,0}; png_init(0, 0); png_open_file(&Png, pFileName); if(Png.color_type != PNG_TRUECOLOR_ALPHA) { dbg_msg("dilate", "%s: not an RGBA image", pFileName); return 1; } pBuffer[0] = (CPixel*)mem_alloc(Png.width*Png.height*sizeof(CPixel), 1); pBuffer[1] = (CPixel*)mem_alloc(Png.width*Png.height*sizeof(CPixel), 1); pBuffer[2] = (CPixel*)mem_alloc(Png.width*Png.height*sizeof(CPixel), 1); png_get_data(&Png, (unsigned char *)pBuffer[0]); png_close_file(&Png); int w = Png.width; int h = Png.height; Dilate(w, h, pBuffer[0], pBuffer[1]); for(int i = 0; i < 5; i++) { Dilate(w, h, pBuffer[1], pBuffer[2]); Dilate(w, h, pBuffer[2], pBuffer[1]); } CopyAlpha(w, h, pBuffer[0], pBuffer[1]); // save here png_open_file_write(&Png, pFileName); png_set_data(&Png, w, h, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)pBuffer[1]); png_close_file(&Png); return 0; }
int main(void) { dbg_logger_stdout(); char aUserdir[1024] = {0}; char aPixelFile[1024] = {0}; int PngCounter = 0; fs_storage_path("Teeworlds", aUserdir, sizeof(aUserdir)); str_format(aPixelFile, sizeof(aPixelFile), "%s/tmp/pixelstream/video.stream", aUserdir); IOHANDLE PixelStream = io_open(aPixelFile, IOFLAG_READ); long long t = 0; long long tOld = 0; long long tOldAdj = 0; unsigned char *pData = 0; unsigned char *pDataOld = 0; unsigned char *pDataMixed = 0; unsigned char *pTempRow = 0; CThreadData *pThreadData = new CThreadData(); mem_zero(pThreadData, sizeof(CThreadData)); int64 StartTime = time_get(); int64 SpeedTime = time_get(); while(PixelStream) { int Size = 0; int W = 0; int H = 0; int len = io_read(PixelStream, &t, sizeof(t)); io_read(PixelStream, &Size, sizeof(Size)); io_read(PixelStream, &W, sizeof(W)); io_read(PixelStream, &H, sizeof(H)); if (len == 0) break; if (!pData) pData = new unsigned char[Size]; if (!pDataOld) pDataOld = new unsigned char[Size]; if (!pDataMixed) pDataMixed = new unsigned char[Size]; if (!pTempRow) pTempRow = new unsigned char[W * 3]; io_read(PixelStream, pData, Size); if (pThreadData->m_Size == 0) { pThreadData->m_Size = Size; pThreadData->m_H = H; pThreadData->m_W = W; thread_detach(thread_create(RotThread, pThreadData)); } int i = 0; while(1) { if (pThreadData->m_pDataIn[i] == 0) { pThreadData->m_CounterIn++; pThreadData->m_aIndexIn[i] = pThreadData->m_CounterIn; unsigned char *p = new unsigned char[Size]; mem_copy(p, pData, Size); pThreadData->m_pDataIn[i] = p; } i++; if (i == 10) break; if (THREADWAITDELAY) thread_sleep(THREADWAITDELAY); } while(1) { int MinIndex = 0; int MinI= 0; for (int i = 0; i < 10; i++) { if (pThreadData->m_pDataOut[i] != 0 && (MinIndex == 0 || MinIndex > pThreadData->m_aIndexOut[i])) { MinIndex = pThreadData->m_aIndexOut[i]; MinI = i; } } if (MinIndex != 0) { mem_copy(pData, pThreadData->m_pDataOut[MinI], Size); delete []pThreadData->m_pDataOut[MinI]; pThreadData->m_pDataOut[MinI] = 0; break; } if (THREADWAITDELAY) thread_sleep(THREADWAITDELAY); } float tAdj = 0.0f; if (tOld && tOld + tAdj + FRAMETIME < t) { while(tOld && tOld + tAdj + FRAMETIME < t) { PngCounter++; char aBuf[1024]; if (PngCounter < 10) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png0000%i.png", aUserdir, PngCounter); if (PngCounter < 100) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png000%i.png", aUserdir, PngCounter); if (PngCounter < 1000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png00%i.png", aUserdir, PngCounter); if (PngCounter < 10000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png0%i.png", aUserdir, PngCounter); if (PngCounter < 100000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png%i.png", aUserdir, PngCounter); #if THREADCOUNT > 0 CBlendThreadData *apBlendData[THREADCOUNT]; for (int i = 0; i < THREADCOUNT; i++) { apBlendData[i] = new CBlendThreadData(); mem_zero(apBlendData[i], sizeof(CBlendThreadData)); apBlendData[i]->m_pIn1 = pData; apBlendData[i]->m_pIn2 = pDataOld; apBlendData[i]->m_pOut = pDataMixed; apBlendData[i]->m_Size = Size; apBlendData[i]->m_Steps = THREADCOUNT; apBlendData[i]->m_Start = i; apBlendData[i]->m_Mix = 1.0f - (tAdj + FRAMETIMEHALF) / ((float)(t - tOld)); thread_detach(thread_create(BlendThread, apBlendData[i])); } while (1) { bool Done = true; for (int i = 0; i < THREADCOUNT; i++) { if (apBlendData[i]->m_Finished == false) { Done = false; break; } } if (THREADWAITDELAY) thread_sleep(THREADWAITDELAY); if (Done) break; } #else for (int i = 0; i < Size; i++) { pDataMixed[i] = mix(pData[i], pDataOld[i], 1.0f - (tAdj + FRAMETIMEHALF) / ((float)(t - tOld))); } #endif png_t Png; png_init(0,0); png_open_file_write(&Png, aBuf); // ignore_convention png_set_data(&Png, W, H, 8, PNG_TRUECOLOR, (unsigned char *)pDataMixed); // ignore_convention png_close_file(&Png); // ignore_convention if (time_get() - SpeedTime > time_freq()) { dbg_msg("Frame", "%i (Avg: %.2f s)", PngCounter, ((float)(time_get() - StartTime) / (float)time_freq()) / (float)PngCounter); dbg_msg("FPS", "%.f", (float)PngCounter / ((float)(time_get() - StartTime) / (float)time_freq())); SpeedTime = time_get(); } tAdj = tAdj + FRAMETIME; } } else { PngCounter++; char aBuf[1024]; if (PngCounter < 10) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png0000%i.png", aUserdir, PngCounter); if (PngCounter < 100) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png000%i.png", aUserdir, PngCounter); if (PngCounter < 1000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png00%i.png", aUserdir, PngCounter); if (PngCounter < 10000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png0%i.png", aUserdir, PngCounter); if (PngCounter < 100000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png%i.png", aUserdir, PngCounter); png_t Png; png_init(0,0); png_open_file_write(&Png, aBuf); // ignore_convention png_set_data(&Png, W, H, 8, PNG_TRUECOLOR, (unsigned char *)pData); // ignore_convention png_close_file(&Png); // ignore_convention if (time_get() - SpeedTime > time_freq()) { dbg_msg("Frame", "%i (Avg: %.2f s)", PngCounter, ((float)(time_get() - StartTime) / (float)time_freq()) / (float)PngCounter); dbg_msg("FPS", "%.f", (float)PngCounter / ((float)(time_get() - StartTime) / (float)time_freq())); SpeedTime = time_get(); } } mem_copy(pDataOld, pData, Size); tOld = t; } delete[] pData; delete[] pDataOld; delete[] pDataMixed; return 0; }