commit 97cc26a21d72b8620340a2c7eb89b1c6b322af26 Author: 蓝冰记忆 Date: Sun Nov 9 14:10:48 2025 +0800 初始化 diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..7f3e308 --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,50 @@ +# AsciiArt 转换程式 + +> 说明:原始的实验报告因为包含真实身份信息,所以不再提供,此处的文本为从原始实验报告中提取出来的部分。 +> 由于年代久远(这个是 2019 年实现的),我已经忘了当时的具体情况,所以我也不确定这玩意到底是怎么用的。将就着参考吧。 + +## 设计思路与功能描述 + +### 设计思路 + +主要是实现了Array类,由于涉及到一些转化操作,因此写了一些转换函数,并注释掉了要求中说明但是对作业无用的函数以提高效率与资源利用率。 + +考虑了复杂空间分配,使用了分层循环申请空间的方法处理高维数组的解析问题。 + +针对播放连续图像需要的环境做了一定的修改适配,但是优化不够,导致卡顿。可以通过引入第三方库进行更多视频的处理。 + +针对不同的调试环境,加入了条件编译。 + +### 功能描述 + +将图片转换成字符,组合输出; + +播放从视频序列里拆出来的图像文件。 + +## 使用说明 + +为了方便使用,已经在core.cpp文件头加入了条件编译切换开关(切换仅图片模式/连续图像播放器模式),取消第一行“#define DEBUG_MODE”的注释即可进入图片模式(此时请不要直接运行,因为默认传入的参数是视频信息,不是图片,会导致报错。 + +**图片模式**运行方法为将图片拖至生成的可执行文件上,会自动显示转换后的结果。使用了getchar()来卡进程,回车键可以结束程序。 + +**播放器模式**运行方法为调试运行。当然,也可以将视频信息文件和序列文件夹放置于与可执行文件同文件夹下,将视频信息文件拖到生成的可执行文件上,即可开始播放。由于采用了多线程异步时钟定时器技术,因此进程并未被阻塞,播放过程中按下回车即可结束程序。 + +**由于压缩文件过大(13MB,服务器上传限制8MB),因此视频图片序列无法上传,具体效果请参考源码自行想象,视频将在一段时间后上传至流媒体服务平台,敬请期待。同时默认模式也已经切换至图片调试模式,方便效果检查,谢谢。** + +## 问题与解决 + +### X、Y与Line、Column不对应的问题 + +我们不能改变程序提供者的想法,所以只要保证自己不要弄混淆就可以了。 + +### 字符宽高问题 + +通过将同一个字符输出两次来解决宽度被压缩的问题。 + +### 文件打开代价 + +暂未解决,以后可能引入视频解码库来解决问题。 + +## 心得体会 + +挺有趣的 diff --git a/Z_3.sln b/Z_3.sln new file mode 100644 index 0000000..9e335a1 --- /dev/null +++ b/Z_3.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.572 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Z_3", "Z_3\Z_3.vcxproj", "{302F7659-80AC-4991-A78E-514675E14B97}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {302F7659-80AC-4991-A78E-514675E14B97}.Debug|x64.ActiveCfg = Debug|x64 + {302F7659-80AC-4991-A78E-514675E14B97}.Debug|x64.Build.0 = Debug|x64 + {302F7659-80AC-4991-A78E-514675E14B97}.Debug|x86.ActiveCfg = Debug|Win32 + {302F7659-80AC-4991-A78E-514675E14B97}.Debug|x86.Build.0 = Debug|Win32 + {302F7659-80AC-4991-A78E-514675E14B97}.Release|x64.ActiveCfg = Release|x64 + {302F7659-80AC-4991-A78E-514675E14B97}.Release|x64.Build.0 = Release|x64 + {302F7659-80AC-4991-A78E-514675E14B97}.Release|x86.ActiveCfg = Release|Win32 + {302F7659-80AC-4991-A78E-514675E14B97}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DC222423-20C7-4D36-B5C1-C58F35D3A3A2} + EndGlobalSection +EndGlobal diff --git a/Z_3/FastPrinter.h b/Z_3/FastPrinter.h new file mode 100644 index 0000000..5c5cf53 --- /dev/null +++ b/Z_3/FastPrinter.h @@ -0,0 +1,327 @@ +/****************************************************************** +* ע⣡ * +* ͷļΪװWinAPIйConsoleƵĵײ㺯԰ * +* ٻҪЧʱprintf+cls߳ܶࡣ * +* ʹdemo.cppеļʾ * +******************************************************************/ +#ifndef FAST_PRINTER_H +#define FAST_PRINTER_H +#include + +/****************************************************************** +* TO-DO: * +* * +* ļɽ޸ģ罫еһЩղΪʵֵArray * +* ΪʵֽһЩЯԱıдȣԼʵ * +* һЧġ * +* * +******************************************************************/ + +namespace fp_color { + // f is the foreground color b is the background color + // console color format: (f | b) + const SHORT f_black = 0; + const SHORT f_blue = 0x0001; + const SHORT f_green = 0x0002; + const SHORT f_aqua = 0x0003; + const SHORT f_red = 0x0004; + const SHORT f_purple = 0x0005; + const SHORT f_yellow = 0x0006; + const SHORT f_white = 0x0007; + const SHORT f_gray = 0x0008; + const SHORT f_l_blue = 0x0009; + const SHORT f_l_green = 0x000A; + const SHORT f_l_aqua = 0x000B; + const SHORT f_l_red = 0x000C; + const SHORT f_l_purple = 0x000D; + const SHORT f_l_yellow = 0x000E; + const SHORT f_l_white = 0x000F; + + const SHORT b_black = 0; + const SHORT b_blue = 0x0010; + const SHORT b_green = 0x0020; + const SHORT b_aqua = 0x0030; + const SHORT b_red = 0x0040; + const SHORT b_purple = 0x0050; + const SHORT b_yellow = 0x0060; + const SHORT b_white = 0x0070; + const SHORT b_gray = 0x0080; + const SHORT b_l_blue = 0x0090; + const SHORT b_l_green = 0x00A0; + const SHORT b_l_aqua = 0x00B0; + const SHORT b_l_red = 0x00C0; + const SHORT b_l_purple = 0x00D0; + const SHORT b_l_yellow = 0x00E0; + const SHORT b_l_white = 0x00F0; +} + +class FastPrinter { +public: + FastPrinter(DWORD, DWORD); + FastPrinter(DWORD, DWORD, WORD); + ~FastPrinter(); + + void setData(const char*, const WORD*); + void setData(const char*, const WORD*, SMALL_RECT); + void setRect(SMALL_RECT, const char, const WORD); + void fillRect(SMALL_RECT, const char, const WORD); + void setText(COORD, const char*, const WORD, const WORD); + void setText(COORD, const char*, const WORD); + void setText(COORD, const char*); + + void cleanSrceen(); + void draw(bool); +private: + HANDLE hOutput, hOutBuf, hTmpBuf; + COORD coordBufSize; + COORD coordBufCoord; + DWORD bytes = 0; + DWORD sizeX, sizeY; + + char* dataGrid; + WORD* colorGrid; + CHAR_INFO* outputGrid; + SMALL_RECT srctWriteRect; + + void initDrawer(); + void _setFontSize(const WORD); + void _destroy(); + + void _swapBuf(); + void _draw(); + void _drawC(); +}; + +FastPrinter::FastPrinter(DWORD x, DWORD y) :sizeX(x), sizeY(y) { + initDrawer(); +} + +FastPrinter::FastPrinter(DWORD x, DWORD y, WORD fontSize) : sizeX(x), sizeY(y) { + // init with font size + _setFontSize(fontSize); + initDrawer(); +} + +FastPrinter::~FastPrinter() { + _destroy(); +} + +void FastPrinter::setData(const char* _in_data, const WORD* _in_color) { + // copy the data to inner buffer + memcpy(dataGrid, _in_data, sizeX * sizeY); + memcpy(colorGrid, _in_color, sizeX * sizeY * sizeof(WORD)); +} + +void FastPrinter::setData(const char* _in_data, const WORD* _in_color, SMALL_RECT _area) { + // copy the data to the specified area + SHORT row = (_area.Right - _area.Left); + for (WORD _i = _area.Top, i = 0; _i < _area.Bottom; _i++, i++) { + memcpy(dataGrid + (_i * sizeX + _area.Left), _in_data + (i * row), row); + memcpy(colorGrid + (_i * sizeX + _area.Left), _in_color + (i * row), row * sizeof(WORD)); + } +} + +void FastPrinter::setRect(SMALL_RECT _area, const char _val, const WORD _color) { + // draw a hollow rectangle + for (WORD i = _area.Left; i < _area.Right; i++) { + dataGrid[_area.Top * sizeX + i] = _val; + dataGrid[(_area.Bottom - 1) * sizeX + i] = _val; + + colorGrid[_area.Top * sizeX + i] = _color; + colorGrid[(_area.Bottom - 1) * sizeX + i] = _color; + } + + for (WORD i = _area.Top; i < _area.Bottom; i++) { + dataGrid[i * sizeX + _area.Left] = _val; + dataGrid[i * sizeX + _area.Right - 1] = _val; + + colorGrid[i * sizeX + _area.Left] = _color; + colorGrid[i * sizeX + _area.Right - 1] = _color; + } +} + +void FastPrinter::fillRect(SMALL_RECT _area, const char _val, const WORD _color) { + // draw a solid rectangle + SHORT row = (_area.Right - _area.Left); + for (WORD _i = _area.Top, i = 0; _i < _area.Bottom; _i++, i++) { + memset(dataGrid + (_i * sizeX + _area.Left), _val, row); + for (WORD _j = _area.Left; _j < _area.Right; _j++) { + colorGrid[_i * sizeX + _j] = _color; + } + } +} + +void FastPrinter::setText(COORD _pos, const char* _val, const WORD _color, const WORD len) { + // print text with position and color + // Note: try not to set text with '\n' + memcpy(dataGrid + (_pos.Y * sizeX + _pos.X), _val, len); + for (WORD i = _pos.X; i < _pos.X + len; i++) { + colorGrid[_pos.Y * sizeX + i] = _color; + } +} + +void FastPrinter::setText(COORD _pos, const char* _val, const WORD _color) { + // print text with position and color but no len + WORD len = (WORD)strlen(_val); + memcpy(dataGrid + (_pos.Y * sizeX + _pos.X), _val, len); + for (WORD i = _pos.X; i < _pos.X + len; i++) { + colorGrid[_pos.Y * sizeX + i] = _color; + } +} + +void FastPrinter::setText(COORD _pos, const char* _val) { + // print text with position but no len + WORD len = (WORD)strlen(_val); + memcpy(dataGrid + (_pos.Y * sizeX + _pos.X), _val, len); + for (WORD i = _pos.X; i < _pos.X + len; i++) { + colorGrid[_pos.Y * sizeX + i] = fp_color::f_l_white; + } +} + +void FastPrinter::_setFontSize(const WORD x) { + CONSOLE_FONT_INFOEX cfi; + cfi.cbSize = sizeof(cfi); + GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi); + cfi.dwFontSize.X = 0; + cfi.dwFontSize.Y = x; + SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi); +} + + +void FastPrinter::cleanSrceen() { + memset(dataGrid, 0, sizeX * sizeY); + memset(colorGrid, 0, sizeX * sizeY * sizeof(WORD)); + memset(outputGrid, 0, sizeX * sizeY * sizeof(CHAR_INFO)); +} + +void FastPrinter::draw(bool withColor) { + // flush the whole screen + if (withColor)_drawC(); + else _draw(); + _swapBuf(); +} + +void FastPrinter::initDrawer() { + // init the data buffer + dataGrid = new char[sizeX * sizeY]; + memset(dataGrid, 0, sizeX * sizeY); + + colorGrid = new WORD[sizeX * sizeY]; + memset(colorGrid, 0, sizeX * sizeY * sizeof(WORD)); + + outputGrid = new CHAR_INFO[sizeX * sizeY]; + memset(outputGrid, 0, sizeX * sizeY * sizeof(CHAR_INFO)); + + // set the draw area + srctWriteRect.Top = 0; + srctWriteRect.Left = 0; + srctWriteRect.Bottom = (SHORT)(sizeY - 1); + srctWriteRect.Right = (SHORT)(sizeX - 1); + + // get font size + CONSOLE_FONT_INFOEX cfi; + cfi.cbSize = sizeof(cfi); + GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi); + + // load the external WinAPI Module + typedef HWND(WINAPI *PROCGETCONSOLEWINDOW)(); + PROCGETCONSOLEWINDOW GetConsoleWindow; + HMODULE hKernel32 = GetModuleHandleA("kernel32"); + GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32, "GetConsoleWindow"); + + // get console window handle and move the window to the upper left + HWND hwnd = GetConsoleWindow(); + SetWindowPos(hwnd, HWND_TOP, 0, 0, cfi.dwFontSize.X * sizeX, cfi.dwFontSize.Y * sizeY, 0); + + // resize the window + char cmd_buffer[32] = "mode con: cols=0000 lines=0000"; + cmd_buffer[15] = '0' + (sizeX / 1000 % 10); + cmd_buffer[16] = '0' + (sizeX / 100 % 10); + cmd_buffer[17] = '0' + (sizeX / 10 % 10); + cmd_buffer[18] = '0' + sizeX % 10; + + cmd_buffer[26] = '0' + (sizeY / 1000 % 10); + cmd_buffer[27] = '0' + (sizeY / 100 % 10); + cmd_buffer[28] = '0' + (sizeY / 10 % 10); + cmd_buffer[29] = '0' + sizeY % 10; + + system(cmd_buffer); + + // create output buffer + hOutBuf = CreateConsoleScreenBuffer( + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, + CONSOLE_TEXTMODE_BUFFER, + NULL + ); + + hOutput = CreateConsoleScreenBuffer( + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, + CONSOLE_TEXTMODE_BUFFER, + NULL + ); + + // invisible the cursor + CONSOLE_CURSOR_INFO cci; + cci.bVisible = 0; + cci.dwSize = 1; + SetConsoleCursorInfo(hOutput, &cci); + SetConsoleCursorInfo(hOutBuf, &cci); +} + +void FastPrinter::_destroy() { + // clean up memory + delete[] dataGrid; + delete[] colorGrid; + delete[] outputGrid; + + CloseHandle(hOutBuf); + CloseHandle(hOutput); +} + +void FastPrinter::_swapBuf() { + // core function: display after the data has been set + hTmpBuf = hOutBuf; + hOutBuf = hOutput; + hOutput = hTmpBuf; +} + +void FastPrinter::_draw() { + for (DWORD i = 0; i < sizeY; i++) { + // draw every line + coordBufCoord.Y = (SHORT)i; + WriteConsoleOutputCharacterA(hOutput, dataGrid + (i * sizeX), sizeX, coordBufCoord, &bytes); + } + SetConsoleActiveScreenBuffer(hOutput); +} + +void FastPrinter::_drawC() { + for (DWORD i = 0; i < sizeY; i++) { + for (DWORD j = 0; j < sizeX; j++) { + // copy info to CHAR_INFO struct + // this will draw with color + outputGrid[i * sizeX + j].Attributes = colorGrid[i * sizeX + j]; + outputGrid[i * sizeX + j].Char.AsciiChar = dataGrid[i * sizeX + j]; + } + } + + coordBufCoord.X = 0; + coordBufCoord.Y = 0; + coordBufSize.X = (SHORT)(sizeX); + coordBufSize.Y = (SHORT)(sizeY); + + WriteConsoleOutputA( + hOutput, // screen buffer to write to + outputGrid, // buffer to copy from + coordBufSize, // col-row size of chiBuffer + coordBufCoord, // top left src cell in chiBuffer + &srctWriteRect); // dest. screen buffer rectangle + SetConsoleActiveScreenBuffer(hOutput); +} +/****************************************************************** +* TO-DO END * +******************************************************************/ +#endif \ No newline at end of file diff --git a/Z_3/PicReader.h b/Z_3/PicReader.h new file mode 100644 index 0000000..e4a8166 --- /dev/null +++ b/Z_3/PicReader.h @@ -0,0 +1,194 @@ +/****************************************************************** +* ע⣡ * +* ͷļΪװWinAPIWICײ㺯ͼƬȡ * +* װⲿ⣬һԼϸ͹涨 * +* ͷļκûTO-DOĵط㲻Ҫ޸ģ⣬ * +* 뼰ʱϵʦ̣ * +* ÿһTO-DOTO-DO˵ (TO-DO) END ɿ· * +* readPic()ΪװWinAPIеķԽͼƬȡΪRGBA * +* bitmapݣⲢͨ޸ֱӴﵽȡҶͼ * +* Ŀġ * +* getData()ҪƵĺȡһάBYTEת * +* ʵֵArrayࡣ * +* testReader()demoṩȡݵһ˼· * +******************************************************************/ +#ifndef PIC_READER_H +#define PIC_READER_H + +#include +#include +#include + +template +inline void SafeRelease(T *&p) { + if (nullptr != p) { + p->Release(); + p = nullptr; + } +} + +class PicReader { +public: + PicReader(); + ~PicReader(); + + void readPic(LPCSTR); + void /*TO-DOҪ޸ķ END*/ getData(/*TO-DOҪ޸Ĵ END*/); + void testReader(BYTE *&,UINT &, UINT &); +private: + void init(); + bool checkHR(HRESULT); + void quitWithError(LPCSTR); + + HWND hWnd; + HANDLE hFile; + IWICImagingFactory *m_pIWICFactory; + IWICFormatConverter *m_pConvertedSourceBitmap; + + /*TO-DOܻҪڲԱ END*/ +}; + +PicReader::PicReader() : m_pConvertedSourceBitmap(nullptr), m_pIWICFactory(nullptr) { + init(); +} + +PicReader::~PicReader() { + if (hFile != NULL) CloseHandle(hFile); + SafeRelease(m_pConvertedSourceBitmap); + SafeRelease(m_pIWICFactory); + CoUninitialize(); +} + +bool PicReader::checkHR(HRESULT hr) { + return (hr < 0); +} + +void PicReader::quitWithError(LPCSTR message) { + MessageBoxA(hWnd, message, "Application Error", MB_ICONEXCLAMATION | MB_OK); + quick_exit(0xffffffff); +} + +void PicReader::init() { + hWnd = GetForegroundWindow(); + + // Enables the terminate-on-corruption feature. + HeapSetInformation(nullptr, HeapEnableTerminationOnCorruption, nullptr, 0); + + HRESULT hr = S_OK; + + //Init the WIC + hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + + // Create WIC factory + hr = CoCreateInstance( + CLSID_WICImagingFactory, + nullptr, + CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&m_pIWICFactory) + ); + + // Throw error if create factor failed + if (checkHR(hr)) { quitWithError("Init Reader Failed"); } +} + +void PicReader::readPic(LPCSTR fileName) { + HRESULT hr = S_OK; + + // Create a File Handle (WinAPI method not std c) + if (hFile != NULL) CloseHandle(hFile); + hFile = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (GetLastError() == ERROR_FILE_NOT_FOUND) { + quitWithError("Cannot find such file, please retry or check the access"); + } + + // Create a decoder + IWICBitmapDecoder *pDecoder = nullptr; + hr = m_pIWICFactory->CreateDecoderFromFileHandle((ULONG_PTR)hFile, nullptr, WICDecodeMetadataCacheOnDemand, &pDecoder); + if (checkHR(hr)) { quitWithError("Create Decoder Failed"); } + + // Retrieve the first frame of the image from the decoder + IWICBitmapFrameDecode *pFrame = nullptr; + hr = pDecoder->GetFrame(0, &pFrame); + if (checkHR(hr)) { quitWithError("Get Frame Failed"); } + + // Format convert the frame to 32bppRGBA + SafeRelease(m_pConvertedSourceBitmap); + hr = m_pIWICFactory->CreateFormatConverter(&m_pConvertedSourceBitmap); + if (checkHR(hr)) { quitWithError("Get Format Converter Failed"); } + + hr = m_pConvertedSourceBitmap->Initialize(pFrame, GUID_WICPixelFormat32bppRGBA, WICBitmapDitherTypeNone, nullptr, 0.f, WICBitmapPaletteTypeCustom); + if (checkHR(hr)) { quitWithError("Init Bitmap Failed"); } + + // Clean memory + SafeRelease(pDecoder); + SafeRelease(pFrame); +} + +void /*TO-DOҪ޸ķ END*/ PicReader::getData(/*TO-DOҪ޸Ĵ END*/) { + HRESULT hr = S_OK; + + // Get the size of Image + UINT x, y; + hr = m_pConvertedSourceBitmap->GetSize(&x, &y); + if (checkHR(hr)) { quitWithError("Check Bitmap Size Failed"); } + + // Create the buffer of pixels, the type of BYTE is unsigned char + BYTE *data; + data = new BYTE[x * y * 4]; + memset(data, 0, x * y * 4); + + // Copy the pixels to the buffer + UINT stride = x * 4; + hr = m_pConvertedSourceBitmap->CopyPixels(nullptr, stride, x * y * 4, data); + if (checkHR(hr)) { quitWithError("Copy Pixels Failed"); } + + /****************************************************************** + * TO-DO: * + * * + * ʵһArray࣬dataתArray * + * * + * ˵Bitmap Copyݣÿ4Ϊһһ * + * ΪһΪͼ(**4)һά * + * ŲΪ R G B A R G B A R G B A..... * + * * + * ע⣡ ֻĶӴ˿ʼһTO-DO ENDλõĴ룡 * + ******************************************************************/ + + delete[] data; + + /****************************************************************** + * TO-DO END * + ******************************************************************/ + + // Close the file handle + CloseHandle(hFile); + hFile = NULL; +} + +void PicReader::testReader(BYTE* &_out, UINT& _x, UINT& _y){ + HRESULT hr = S_OK; + + // Get the size of Image + UINT x, y; + hr = m_pConvertedSourceBitmap->GetSize(&x, &y); + if (checkHR(hr)) { quitWithError("Check Bitmap Size Failed"); } + + // Create the buffer of pixels, the type of BYTE is unsigned char + BYTE *data; + data = new BYTE[x * y * 4]; + memset(data, 0, x * y * 4); + + // Copy the pixels to the buffer + UINT stride = x * 4; + hr = m_pConvertedSourceBitmap->CopyPixels(nullptr, stride, x * y * 4, data); + if (checkHR(hr)) { quitWithError("Copy Pixels Failed"); } + + + _out = data; _x = x; _y = y; + + // Close the file handle + CloseHandle(hFile); + hFile = NULL; +} + +#endif \ No newline at end of file diff --git a/Z_3/Z_3.vcxproj b/Z_3/Z_3.vcxproj new file mode 100644 index 0000000..1fcdedf --- /dev/null +++ b/Z_3/Z_3.vcxproj @@ -0,0 +1,164 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + 15.0 + {302F7659-80AC-4991-A78E-514675E14B97} + Win32Proj + Z3 + 10.0.17134.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + pch.h + + + Console + true + + + + + NotUsing + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + pch.h + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + pch.h + + + Console + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + pch.h + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/Z_3/Z_3.vcxproj.filters b/Z_3/Z_3.vcxproj.filters new file mode 100644 index 0000000..97d12e2 --- /dev/null +++ b/Z_3/Z_3.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Header Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/Z_3/Z_3.vcxproj.user b/Z_3/Z_3.vcxproj.user new file mode 100644 index 0000000..7568925 --- /dev/null +++ b/Z_3/Z_3.vcxproj.user @@ -0,0 +1,7 @@ + + + + "bg.jpg" + WindowsLocalDebugger + + \ No newline at end of file diff --git a/Z_3/array.h b/Z_3/array.h new file mode 100644 index 0000000..add742d --- /dev/null +++ b/Z_3/array.h @@ -0,0 +1,11 @@ +template +class Array { + private: + int dimension_count; + int * dim_size; + + T * entry_point; + + + public: +}; \ No newline at end of file diff --git a/Z_3/core-bkup.cpp b/Z_3/core-bkup.cpp new file mode 100644 index 0000000..a1ac817 --- /dev/null +++ b/Z_3/core-bkup.cpp @@ -0,0 +1,400 @@ +//#define _DEBUG_MODE + +#include "PicReader.h" +#include "FastPrinter.h" + +class Array { + private: + BYTE * * * arr_header; + UINT line; + UINT col; + UINT depth; + + public: + //Array(const UINT, const UINT, const UINT); + Array(BYTE * data, UINT l, UINT c, UINT d) : line(l), col(c), depth(d) { + + arr_header = new BYTE * * [l]; + for (UINT i = 0; i < l; i++) { + arr_header[i] = new BYTE * [c]; + for (UINT j = 0; j < c; j++) { + arr_header[i][j] = new BYTE[d]; + } + } + + for (UINT i = 0; i < l; i++) { + for (UINT j = 0; j < c; j++) { + for (UINT k = 0; k < d; k++) { + arr_header[i][j][k] = data[(i * c + j) * d + k]; + } + } + } + } + //Array(Array &); + + ~Array(); + + BYTE * * operator [] (UINT & line_no) const { + return *(arr_header + line_no); + } + + /*BYTE * operator () (UINT & line_no, UINT & col_no) const { + return *(*(arr_header + line_no) + col_no); + } + BYTE & operator () (UINT & line_no, UINT & col_no, UINT & dep_no) const { + return *(*(*(arr_header + line_no) + col_no) + dep_no); + }*/ + + //friend Array operator + (Array &, Array &); + //friend Array operator - (Array &, Array &); + //friend Array operator * (Array &, Array &); + //friend Array operator / (Array &, Array &); + + //Array & operator = (const Array &); + + /*void reshape(const UINT l = 0, const UINT c = 1, const UINT d = 1) { + if (arr_header != nullptr) { + delete[] arr_header; + } + line = l; col = c; depth = d; + if (l * c * d != 0) { + arr_header = (BYTE * * *) new BYTE[l*c*d]; + } else { + arr_header = nullptr; + } + }*/ + + + friend BYTE * * * RGB2Grey(Array &); + +}; + +//Array::Array(const UINT l = 0, const UINT c = 1, const UINT d = 1) : line(l), col(c), depth(d) { +// if (l * c * d != 0) { +// arr_header = new BYTE * * [l]; +// for (UINT i = 0; i < l; i++) { +// arr_header[i] = new BYTE * [c]; +// for (UINT j = 0; j < c; j++) { +// arr_header[i][j] = new BYTE[d]; +// } +// } +// } else { +// arr_header = nullptr; +// } +//} + +//Array::Array(Array & A0) { +// line = A0.line; col = A0.col; depth = A0.depth; +// reshape(line, col, depth); +// for (UINT i = 0; i < A0.line && i < line; i++) { +// for (UINT j = 0; j < A0.col && i < col; j++) { +// for (UINT k = 0; k < A0.depth && i < depth; k++) { +// *(*(*(arr_header + i) + j) + k) = A0[i][j][k]; +// } +// } +// } +//} + +Array::~Array() { + for (UINT i = 0; i < line; i++) { + for (UINT j = 0; j < col; j++) { + delete[] arr_header[i][j]; + } + delete[] arr_header[i]; + } + delete[] arr_header; +} + +//Array operator + (Array & A1, Array & A2) { +// if (A1.line != A2.line || A1.col != A2.col || A1.depth != A2.depth) { +// throw "矩阵大小不一致!"; +// } +// Array ans(A1.line, A1.col, A1.depth); +// for (UINT i = 0; i < A1.line; i++) { +// for (UINT j = 0; j < A1.col; j++) { +// for (UINT k = 0; k < A1.depth; k++) { +// ans[i][j][k] = A1[i][j][k] + A2[i][j][k]; +// } +// } +// } +// return ans; +//} +// +//Array operator - (Array & A1, Array & A2) { +// if (A1.line != A2.line || A1.col != A2.col || A1.depth != A2.depth) { +// throw "矩阵大小不一致!"; +// } +// Array ans(A1.line, A1.col, A1.depth); +// for (UINT i = 0; i < A1.line; i++) { +// for (UINT j = 0; j < A1.col; j++) { +// for (UINT k = 0; k < A1.depth; k++) { +// ans[i][j][k] = A1[i][j][k] - A2[i][j][k]; +// } +// } +// } +// return ans; +//} +// +//Array operator * (Array & A1, Array & A2) { +// if (A1.line != A2.line || A1.col != A2.col || A1.depth != A2.depth) { +// throw "矩阵大小不一致!"; +// } +// Array ans(A1.line, A1.col, A1.depth); +// for (UINT i = 0; i < A1.line; i++) { +// for (UINT j = 0; j < A1.col; j++) { +// for (UINT k = 0; k < A1.depth; k++) { +// ans[i][j][k] = A1[i][j][k] * A2[i][j][k]; +// } +// } +// } +// return ans; +//} +// +//Array operator / (Array & A1, Array & A2) { +// if (A1.line != A2.line || A1.col != A2.col || A1.depth != A2.depth) { +// throw "矩阵大小不一致!"; +// } +// Array ans(A1.line, A1.col, A1.depth); +// for (UINT i = 0; i < A1.line; i++) { +// for (UINT j = 0; j < A1.col; j++) { +// for (UINT k = 0; k < A1.depth; k++) { +// ans[i][j][k] = A1[i][j][k] / A2[i][j][k]; +// } +// } +// } +// return ans; +//} + +//Array & Array::operator = (const Array & A0) { +// line = A0.line; col = A0.col; depth = A0.depth; +// reshape(line, col, depth); +// for (UINT i = 0; i < A0.line && i < line; i++) { +// for (UINT j = 0; j < A0.col && i < col; j++) { +// for (UINT k = 0; k < A0.depth && i < depth; k++) { +// *(*(*(arr_header + i) + j) + k) = A0[i][j][k]; +// } +// } +// } +// return *this; +//} + +// Specified functions for this project only + +BYTE * * * RGB2Grey(Array & RGB_Arr) { + for (UINT i = 0; i < RGB_Arr.line; i++) { + for (UINT j = 0; j < RGB_Arr.col; j++) { + RGB_Arr[i][j][0] = BYTE((RGB_Arr[i][j][0] * 299 + RGB_Arr[i][j][1] * 587 + RGB_Arr[i][j][2] * 114) / 1100); + + } + } + //RGB.reshape(RGB.line, RGB.col, 1); + return RGB_Arr.arr_header; +} + + +BYTE * * Grey2BYTE(BYTE * * * From, UINT line, UINT col) { + const BYTE asciiStrength[] = { 'M','N','H','Q','$','O','C','?','!',':','-','.' }; + BYTE * * Result = new BYTE * [line]; + for (UINT i = 0; i < line; i++) { + Result[i] = new BYTE[col]; + } + for (UINT i = 0; i < line; i++) { + for (UINT j = 0; j < col; j++) { + Result[i][j] = asciiStrength[From[i][j][0] / 21]; + } + //Result[i][col] = '\0'; + } + return Result; +} + + +#include + +#define _DBL_CHR + +#ifdef _DEBUG_MODE +int main(int argc, char * * argv) { + + PicReader imread; + BYTE *data = nullptr; + UINT line, col; + + if (argc == 1) { + imread.readPic("test.png"); + } else if (argc == 2) { + imread.readPic(argv[1]); + } + + imread.testReader(data, col, line); + + Array pic(data, line, col, 4); + delete[] data; + + BYTE * * ResDat = Grey2BYTE(RGB2Grey(pic), line, col); + +#ifdef _DBL_CHR + FastPrinter printer(col * 2, line, 1); +#else + FastPrinter printer(col, line, 1); +#endif + COORD picXY; + printer.cleanSrceen(); + picXY.X = 0; +#ifdef _DBL_CHR + char * Line = new char[col * 2]; +#endif + for (unsigned i = 0; i < line; i++) { + picXY.Y = i; + + #ifdef _DBL_CHR + for (UINT j = 0; j < col; j++) { + Line[j * 2] = ResDat[i][j]; + Line[j * 2 + 1] = ResDat[i][j]; + } + printer.setText(picXY, Line, (fp_color::f_black | fp_color::b_l_white), col * 2); + #else + printer.setText(picXY, (char *)(ResDat[i]), (fp_color::f_black | fp_color::b_l_white), col); + #endif + + } + +#ifdef _DBL_CHR + delete[] Line; +#endif + + printer.draw(true); + + for (UINT i = 0; i < line; i++) { + delete[] ResDat[i]; + } + delete[] ResDat; + + getchar(); + + return 0; + +} + +#else + +#include "timer.h" +#include + +static PicReader * FrameLoader; +static BYTE *FrameData = nullptr; +static UINT Vline, Vcol; +static unsigned CntLen, FrameNum; +static unsigned Interval = 0; +static char FramePath[50] = { 0 }; +static unsigned FrontPathLen = 0; +static BYTE * * * ResDat; +static COORD LineXY; +static FastPrinter * FramePrinter; + +Timer t; + +void ResDatInit() { + printf("按下回车开始读取资源文件…\n"); + getchar(); + for (UINT i = 1; i <= FrameNum; i++) { + int TmpCnt = i; + for (int j = CntLen; j > 0; j--) { + FramePath[FrontPathLen + j] = '0' + TmpCnt % 10; + TmpCnt /= 10; + } + FrameLoader->readPic(FramePath); + FrameLoader->testReader(FrameData, Vcol, Vline); + Array pic(FrameData, Vline, Vcol, 4); + delete[] FrameData; + ResDat[i] = Grey2BYTE(RGB2Grey(pic), Vline, Vcol); + printf("资源文件%u/%u读取完成\n", i, FrameNum); + } + +} + +// 播放器初始化 +void PlayerInit(const char * FilePath) { + + std::ifstream inf(FilePath); + inf >> Vcol >> Vline; + inf >> CntLen >> FrameNum; + inf >> Interval; + inf >> FramePath; + inf.close(); + + while (FramePath[++FrontPathLen]); + FramePath[FrontPathLen] = ' '; + FramePath[FrontPathLen + CntLen + 1] = '.'; + FramePath[FrontPathLen + CntLen + 2] = 'j'; + FramePath[FrontPathLen + CntLen + 3] = 'p'; + FramePath[FrontPathLen + CntLen + 4] = 'g'; + + FrameLoader = new PicReader; + ResDat = new BYTE * * [FrameNum]; + + ResDatInit(); + + FramePrinter = new FastPrinter(Vcol * 2, Vline, 1); + + LineXY.X = 0; + FramePrinter->cleanSrceen(); +} + +void PlayFinish() { + + delete[] ResDat; + + delete FrameLoader; + delete FramePrinter; + +} + +// 渲染当前帧并准备下一帧 +void FrameEvent() { + static unsigned FrameCounter = 0; + + FramePrinter->draw(true); + FrameCounter++; + if (FrameCounter >= FrameNum) { + t.Expire(); + PlayFinish(); + return; + } + + FramePrinter->cleanSrceen(); + char * Line = new char[Vcol * 2]; + for (unsigned i = 0; i < Vline; i++) { + LineXY.Y = i; + for (UINT j = 0; j < Vcol; j++) { + Line[j * 2] = ResDat[FrameCounter][i][j]; + Line[j * 2 + 1] = ResDat[FrameCounter][i][j]; + } + FramePrinter->setText(LineXY, Line, (fp_color::f_black | fp_color::b_l_white), Vcol * 2); + } + for (UINT i = 0; i < Vline; i++) { + delete[] ResDat[FrameCounter][i]; + } + delete[] ResDat[FrameCounter]; + delete[] Line; + +} + + +int main(int argc, char * * argv) { + if (argc == 1) { + printf("请将视频信息文件拖放至此可执行文件以进行播放,谢谢!"); + getchar(); + return 0; + } + + PlayerInit(argv[1]); + + t.StartTimer(Interval, std::bind(FrameEvent)); + + getchar(); + + return 0; +} + + +#endif \ No newline at end of file diff --git a/Z_3/core.cpp b/Z_3/core.cpp new file mode 100644 index 0000000..c1af70f --- /dev/null +++ b/Z_3/core.cpp @@ -0,0 +1,387 @@ +#define _DEBUG_MODE + +#include "PicReader.h" +#include "FastPrinter.h" + +class Array { + private: + BYTE * * * arr_header; + UINT line; + UINT col; + UINT depth; + + public: + //Array(const UINT, const UINT, const UINT); + Array(BYTE * data, UINT l, UINT c, UINT d) : line(l), col(c), depth(d) { + + arr_header = new BYTE * * [l]; + for (UINT i = 0; i < l; i++) { + arr_header[i] = new BYTE * [c]; + for (UINT j = 0; j < c; j++) { + arr_header[i][j] = new BYTE[d]; + } + } + + for (UINT i = 0; i < l; i++) { + for (UINT j = 0; j < c; j++) { + for (UINT k = 0; k < d; k++) { + arr_header[i][j][k] = data[(i * c + j) * d + k]; + } + } + } + } + //Array(Array &); + + ~Array(); + + BYTE * * operator [] (UINT & line_no) const { + return *(arr_header + line_no); + } + + /*BYTE * operator () (UINT & line_no, UINT & col_no) const { + return *(*(arr_header + line_no) + col_no); + } + BYTE & operator () (UINT & line_no, UINT & col_no, UINT & dep_no) const { + return *(*(*(arr_header + line_no) + col_no) + dep_no); + }*/ + + //friend Array operator + (Array &, Array &); + //friend Array operator - (Array &, Array &); + //friend Array operator * (Array &, Array &); + //friend Array operator / (Array &, Array &); + + //Array & operator = (const Array &); + + /*void reshape(const UINT l = 0, const UINT c = 1, const UINT d = 1) { + if (arr_header != nullptr) { + delete[] arr_header; + } + line = l; col = c; depth = d; + if (l * c * d != 0) { + arr_header = (BYTE * * *) new BYTE[l*c*d]; + } else { + arr_header = nullptr; + } + }*/ + + + friend BYTE * * * RGB2Grey(Array &); + +}; + +//Array::Array(const UINT l = 0, const UINT c = 1, const UINT d = 1) : line(l), col(c), depth(d) { +// if (l * c * d != 0) { +// arr_header = new BYTE * * [l]; +// for (UINT i = 0; i < l; i++) { +// arr_header[i] = new BYTE * [c]; +// for (UINT j = 0; j < c; j++) { +// arr_header[i][j] = new BYTE[d]; +// } +// } +// } else { +// arr_header = nullptr; +// } +//} + +//Array::Array(Array & A0) { +// line = A0.line; col = A0.col; depth = A0.depth; +// reshape(line, col, depth); +// for (UINT i = 0; i < A0.line && i < line; i++) { +// for (UINT j = 0; j < A0.col && i < col; j++) { +// for (UINT k = 0; k < A0.depth && i < depth; k++) { +// *(*(*(arr_header + i) + j) + k) = A0[i][j][k]; +// } +// } +// } +//} + +Array::~Array() { + for (UINT i = 0; i < line; i++) { + for (UINT j = 0; j < col; j++) { + delete[] arr_header[i][j]; + } + delete[] arr_header[i]; + } + delete[] arr_header; +} + +//Array operator + (Array & A1, Array & A2) { +// if (A1.line != A2.line || A1.col != A2.col || A1.depth != A2.depth) { +// throw "Сһ£"; +// } +// Array ans(A1.line, A1.col, A1.depth); +// for (UINT i = 0; i < A1.line; i++) { +// for (UINT j = 0; j < A1.col; j++) { +// for (UINT k = 0; k < A1.depth; k++) { +// ans[i][j][k] = A1[i][j][k] + A2[i][j][k]; +// } +// } +// } +// return ans; +//} +// +//Array operator - (Array & A1, Array & A2) { +// if (A1.line != A2.line || A1.col != A2.col || A1.depth != A2.depth) { +// throw "Сһ£"; +// } +// Array ans(A1.line, A1.col, A1.depth); +// for (UINT i = 0; i < A1.line; i++) { +// for (UINT j = 0; j < A1.col; j++) { +// for (UINT k = 0; k < A1.depth; k++) { +// ans[i][j][k] = A1[i][j][k] - A2[i][j][k]; +// } +// } +// } +// return ans; +//} +// +//Array operator * (Array & A1, Array & A2) { +// if (A1.line != A2.line || A1.col != A2.col || A1.depth != A2.depth) { +// throw "Сһ£"; +// } +// Array ans(A1.line, A1.col, A1.depth); +// for (UINT i = 0; i < A1.line; i++) { +// for (UINT j = 0; j < A1.col; j++) { +// for (UINT k = 0; k < A1.depth; k++) { +// ans[i][j][k] = A1[i][j][k] * A2[i][j][k]; +// } +// } +// } +// return ans; +//} +// +//Array operator / (Array & A1, Array & A2) { +// if (A1.line != A2.line || A1.col != A2.col || A1.depth != A2.depth) { +// throw "Сһ£"; +// } +// Array ans(A1.line, A1.col, A1.depth); +// for (UINT i = 0; i < A1.line; i++) { +// for (UINT j = 0; j < A1.col; j++) { +// for (UINT k = 0; k < A1.depth; k++) { +// ans[i][j][k] = A1[i][j][k] / A2[i][j][k]; +// } +// } +// } +// return ans; +//} + +//Array & Array::operator = (const Array & A0) { +// line = A0.line; col = A0.col; depth = A0.depth; +// reshape(line, col, depth); +// for (UINT i = 0; i < A0.line && i < line; i++) { +// for (UINT j = 0; j < A0.col && i < col; j++) { +// for (UINT k = 0; k < A0.depth && i < depth; k++) { +// *(*(*(arr_header + i) + j) + k) = A0[i][j][k]; +// } +// } +// } +// return *this; +//} + + +BYTE * * * RGB2Grey(Array & RGB_Arr) { + for (UINT i = 0; i < RGB_Arr.line; i++) { + for (UINT j = 0; j < RGB_Arr.col; j++) { + RGB_Arr[i][j][0] = BYTE((RGB_Arr[i][j][0] * 299 + RGB_Arr[i][j][1] * 587 + RGB_Arr[i][j][2] * 114) / 1100); + + } + } + //RGB.reshape(RGB.line, RGB.col, 1); + return RGB_Arr.arr_header; +} + + +BYTE * * Grey2BYTE(BYTE * * * From, UINT line, UINT col) { + const BYTE asciiStrength[] = { 'M','N','H','Q','$','O','C','?','!',':','-','.' }; + BYTE * * Result = new BYTE * [line]; + for (UINT i = 0; i < line; i++) { + Result[i] = new BYTE[col]; + } + for (UINT i = 0; i < line; i++) { + for (UINT j = 0; j < col; j++) { + Result[i][j] = asciiStrength[From[i][j][0] / 21]; + } + //Result[i][col] = '\0'; + } + return Result; +} + + +#include + +#define _DBL_CHR + +#ifdef _DEBUG_MODE +int main(int argc, char * * argv) { + + PicReader imread; + BYTE *data = nullptr; + UINT line, col; + + if (argc == 1) { + imread.readPic("test.png"); + } else if (argc == 2) { + imread.readPic(argv[1]); + } + + imread.testReader(data, col, line); + + Array pic(data, line, col, 4); + delete[] data; + + BYTE * * ResDat = Grey2BYTE(RGB2Grey(pic), line, col); + +#ifdef _DBL_CHR + FastPrinter printer(col * 2, line, 1); +#else + FastPrinter printer(col, line, 1); +#endif + COORD picXY; + printer.cleanSrceen(); + picXY.X = 0; +#ifdef _DBL_CHR + char * Line = new char[col * 2]; +#endif + for (unsigned i = 0; i < line; i++) { + picXY.Y = i; + + #ifdef _DBL_CHR + for (UINT j = 0; j < col; j++) { + Line[j * 2] = ResDat[i][j]; + Line[j * 2 + 1] = ResDat[i][j]; + } + printer.setText(picXY, Line, (fp_color::f_black | fp_color::b_l_white), col * 2); + #else + printer.setText(picXY, (char *)(ResDat[i]), (fp_color::f_black | fp_color::b_l_white), col); + #endif + + } + +#ifdef _DBL_CHR + delete[] Line; +#endif + + printer.draw(true); + + for (UINT i = 0; i < line; i++) { + delete[] ResDat[i]; + } + delete[] ResDat; + + getchar(); + + return 0; + +} + +#else + +#include "timer.h" +#include + +static PicReader * FrameLoader; +static BYTE *FrameData = nullptr; +static UINT Vline, Vcol; +static unsigned CntLen, CntFin; +static unsigned Interval = 0; +static char FramePath[50] = { 0 }; +static unsigned FrontPathLen = 0; +static COORD LineXY; +static BYTE * * ResDat; +static FastPrinter * FramePrinter; + +Timer t; + + +// ʼ +void PlayerInit(const char * FilePath) { + + std::ifstream inf(FilePath); + inf >> Vcol >> Vline; + inf >> CntLen >> CntFin; + inf >> Interval; + inf >> FramePath; + inf.close(); + + FrameLoader = new PicReader; + FramePrinter = new FastPrinter(Vcol * 2, Vline, 8); + + while (FramePath[++FrontPathLen]); + FramePath[FrontPathLen] = ' '; + FramePath[FrontPathLen + CntLen + 1] = '.'; + FramePath[FrontPathLen + CntLen + 2] = 'j'; + FramePath[FrontPathLen + CntLen + 3] = 'p'; + FramePath[FrontPathLen + CntLen + 4] = 'g'; + + LineXY.X = 0; + FramePrinter->cleanSrceen(); +} + +void PlayFinish() { + + delete FrameLoader; + delete FramePrinter; + +} + +// Ⱦǰ֡׼һ֡ +void FrameEvent() { + static unsigned FrameCounter = 0; + + FramePrinter->draw(true); + FrameCounter++; + if (FrameCounter >= CntFin) { + t.Expire(); + PlayFinish(); + return; + } + int TmpCnt = FrameCounter; + for (int i = CntLen; i > 0; i--) { + FramePath[FrontPathLen + i] = '0' + TmpCnt % 10; + TmpCnt /= 10; + } + FrameLoader->readPic(FramePath); + FrameLoader->testReader(FrameData, Vcol, Vline); + Array pic(FrameData, Vline, Vcol, 4); + delete[] FrameData; + ResDat = Grey2BYTE(RGB2Grey(pic), Vline, Vcol); + FramePrinter->cleanSrceen(); + char * Line = new char[Vcol * 2]; + for (unsigned i = 0; i < Vline; i++) { + LineXY.Y = i; + for (UINT j = 0; j < Vcol; j++) { + Line[j * 2] = ResDat[i][j]; + Line[j * 2 + 1] = ResDat[i][j]; + } + FramePrinter->setText(LineXY, Line, (fp_color::f_black | fp_color::b_l_white), Vcol * 2); + } + for (UINT i = 0; i < Vline; i++) { + delete[] ResDat[i]; + } + delete[] ResDat; + delete[] Line; + +} + + +int main(int argc, char * * argv) { + if (argc == 1) { + printf("뽫ƵϢļϷ˿ִļԽвţлл"); + getchar(); + return 0; + } + + PlayerInit(argv[1]); + + t.StartTimer(Interval, std::bind(FrameEvent)); + + getchar(); + + t.Expire(); + PlayFinish(); + + return 0; +} + + +#endif \ No newline at end of file diff --git a/Z_3/timer.h b/Z_3/timer.h new file mode 100644 index 0000000..9d88992 --- /dev/null +++ b/Z_3/timer.h @@ -0,0 +1,91 @@ +#ifndef TIMER_H_ +#define TIMER_H_ +#include +#include +#include +#include +#include +#include +#include +class Timer +{ +public: + Timer() :expired_(true), try_to_expire_(false) {} + Timer(const Timer & t) { + expired_ = t.expired_.load(); + try_to_expire_ = t.try_to_expire_.load(); + } + + ~Timer() { + Expire(); + // std::cout << "timer destructed!" << std::endl; + } + + void StartTimer(int interval, std::function task) { + if (expired_ == false) + { + // std::cout << "timer is currently running, please expire it first..." << std::endl; + return; + } + expired_ = false; + std::thread([this, interval, task]() { + while (!try_to_expire_) { + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); + task(); + } + // std::cout << "stop task..." << std::endl; + { + std::lock_guard locker(mutex_); + expired_ = true; + expired_cond_.notify_one(); + } + }).detach(); + } + + void Expire() { + if (expired_) { + return; + } + + if (try_to_expire_) { + // std::cout << "timer is trying to expire, please wait..." << std::endl; + return; + } + try_to_expire_ = true; + { + std::unique_lock locker(mutex_); + expired_cond_.wait(locker, [this] {return expired_ == true; }); + if (expired_ == true) { + // std::cout << "timer expired!" << std::endl; + try_to_expire_ = false; + } + } + } + + template + void SyncWait(int after, callable&& f, arguments&&... args) { + + std::function::type()> task + (std::bind(std::forward(f), std::forward(args)...)); + std::this_thread::sleep_for(std::chrono::milliseconds(after)); + task(); + } + + template + void AsyncWait(int after, callable&& f, arguments&&... args) { + std::function::type()> task + (std::bind(std::forward(f), std::forward(args)...)); + + std::thread([after, task]() { + std::this_thread::sleep_for(std::chrono::milliseconds(after)); + task(); + }).detach(); + } + +private: + std::atomic expired_; + std::atomic try_to_expire_; + std::mutex mutex_; + std::condition_variable expired_cond_; +}; +#endif \ No newline at end of file diff --git a/Z_3/video4.info b/Z_3/video4.info new file mode 100644 index 0000000..127bbd9 --- /dev/null +++ b/Z_3/video4.info @@ -0,0 +1,4 @@ +128 96 +4 6572 +33 +rena2-4\rena2-4 \ No newline at end of file