msrle32.c
来自「Wine-20031016」· C语言 代码 · 共 1,915 行 · 第 1/4 页
C
1,915 行
return ICERR_BADPARAM; TRACE("lpic={0x%lX,%p,%p,%p,%p,%p,%p,%ld,%lu,%lu,%p,%p}\n",lpic->dwFlags,lpic->lpbiOutput,lpic->lpOutput,lpic->lpbiInput,lpic->lpInput,lpic->lpckid,lpic->lpdwFlags,lpic->lFrameNum,lpic->dwFrameSize,lpic->dwQuality,lpic->lpbiPrev,lpic->lpPrev); if (! pi->bCompress) { LRESULT hr = CompressBegin(pi, lpic->lpbiInput, lpic->lpbiOutput); if (hr != ICERR_OK) return hr; } else if (CompressQuery(pi, lpic->lpbiInput, lpic->lpbiOutput) != ICERR_OK) return ICERR_BADFORMAT; if (lpic->lFrameNum >= pi->nPrevFrame + 1) { /* we continue in the sequence so we need to initialize * our internal framedata */ computeInternalFrame(pi, lpic->lpbiInput, lpic->lpInput); } else if (lpic->lFrameNum == pi->nPrevFrame) { /* Oops, compress same frame again ? Okay, as you wish. * No need to recompute internal framedata, because we only swapped buffers */ LPWORD pTmp = pi->pPrevFrame; pi->pPrevFrame = pi->pCurFrame; pi->pCurFrame = pTmp; } else if ((lpic->dwFlags & ICCOMPRESS_KEYFRAME) == 0) { LPWORD pTmp; WARN(": prev=%ld cur=%ld gone back? -- untested",pi->nPrevFrame,lpic->lFrameNum); if (lpic->lpbiPrev == NULL || lpic->lpPrev == NULL) return ICERR_GOTOKEYFRAME; /* Need a keyframe if you go back */ if (CompressQuery(pi, lpic->lpbiPrev, lpic->lpbiOutput) != ICERR_OK) return ICERR_BADFORMAT; WARN(": prev=%ld cur=%ld compute swapped -- untested\n",pi->nPrevFrame,lpic->lFrameNum); computeInternalFrame(pi, lpic->lpbiPrev, lpic->lpPrev); /* swap buffers for current and previous frame */ /* Don't free and alloc new -- costs to much time and they are of equal size ! */ pTmp = pi->pPrevFrame; pi->pPrevFrame = pi->pCurFrame; pi->pCurFrame = pTmp; pi->nPrevFrame = lpic->lFrameNum; } for (i = 0; i < 3; i++) { SetQuality(pi, lpic->dwQuality); lpic->lpbiOutput->biSizeImage = 0; if (lpic->lpbiOutput->biBitCount == 4) MSRLE32_CompressRLE4(pi, lpic->lpbiInput, (LPBYTE)lpic->lpInput, lpic->lpbiOutput, (LPBYTE)lpic->lpOutput, (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0); else MSRLE32_CompressRLE8(pi, lpic->lpbiInput, (LPBYTE)lpic->lpInput, lpic->lpbiOutput, (LPBYTE)lpic->lpOutput, (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0); if (lpic->dwFrameSize == 0 || lpic->lpbiOutput->biSizeImage < lpic->dwFrameSize) break; if ((*lpic->lpdwFlags & ICCOMPRESS_KEYFRAME) == 0) { if (lpic->lpbiOutput->biBitCount == 4) MSRLE32_CompressRLE4(pi, lpic->lpbiInput, (LPBYTE)lpic->lpInput, lpic->lpbiOutput, (LPBYTE)lpic->lpOutput, TRUE); else MSRLE32_CompressRLE8(pi, lpic->lpbiInput, (LPBYTE)lpic->lpInput, lpic->lpbiOutput, (LPBYTE)lpic->lpOutput, TRUE); if (lpic->dwFrameSize == 0 || lpic->lpbiOutput->biSizeImage < lpic->dwFrameSize) { WARN("switched to keyframe, was small enough!\n"); *lpic->lpdwFlags |= ICCOMPRESS_KEYFRAME; *lpic->lpckid = MAKEAVICKID(cktypeDIBbits, StreamFromFOURCC(*lpic->lpckid)); break; } } if (lpic->dwQuality < 1000) break; lpic->dwQuality -= 1000; /* reduce quality by 10% */ } { /* swap buffer for current and previous frame */ /* Don't free and alloc new -- costs to much time and they are of equal size ! */ register LPWORD pTmp = pi->pPrevFrame; pi->pPrevFrame = pi->pCurFrame; pi->pCurFrame = pTmp; pi->nPrevFrame = lpic->lFrameNum; } return ICERR_OK;}static LRESULT CompressEnd(CodecInfo *pi){ TRACE("(%p)\n",pi); if (pi != NULL) { if (pi->pPrevFrame != NULL) GlobalFreePtr(pi->pPrevFrame); if (pi->pCurFrame != NULL) GlobalFreePtr(pi->pCurFrame); pi->pPrevFrame = NULL; pi->pCurFrame = NULL; pi->nPrevFrame = -1; pi->bCompress = FALSE; } return ICERR_OK;}static LRESULT DecompressGetFormat(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut){ int size; TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); /* pre-condition */ assert(pi != NULL); if (lpbiIn == NULL) return (lpbiOut != NULL ? ICERR_BADPARAM : 0); if (DecompressQuery(pi, lpbiIn, NULL) != ICERR_OK) return (lpbiOut != NULL ? ICERR_BADFORMAT : 0); size = lpbiIn->biSize; if (lpbiOut != NULL) { memcpy(lpbiOut, lpbiIn, size); lpbiOut->biBitCount = 32; lpbiOut->biCompression = BI_RGB; lpbiOut->biSizeImage = DIBWIDTHBYTES(*lpbiOut) * lpbiOut->biHeight; lpbiOut->biClrImportant = 0; if (lpbiOut->biBitCount <= 8 && lpbiOut->biClrUsed == 0) lpbiOut->biClrUsed = 1 << lpbiOut->biBitCount; else lpbiOut->biClrUsed = 0; return size; } else return size;}static LRESULT DecompressQuery(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER lpbiOut){ LRESULT hr = ICERR_OK; TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); /* pre-condition */ assert(pi != NULL); /* need atleast one format */ if (lpbiIn == NULL && lpbiOut == NULL) return ICERR_BADPARAM; /* check input format if given */ if (lpbiIn != NULL) { if (!isSupportedMRLE(lpbiIn)) return ICERR_BADFORMAT; } /* check output format if given */ if (lpbiOut != NULL) { if (!isSupportedDIB(lpbiOut)) hr = ICERR_BADFORMAT; if (lpbiIn != NULL) { if (lpbiIn->biWidth != lpbiOut->biWidth) hr = ICERR_UNSUPPORTED; if (lpbiIn->biHeight != lpbiOut->biHeight) hr = ICERR_UNSUPPORTED; if (lpbiIn->biBitCount > lpbiOut->biBitCount) hr = ICERR_UNSUPPORTED; } } return hr;}static LRESULT DecompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER lpbiOut){ const RGBQUAD *rgbIn; const RGBQUAD *rgbOut; UINT i; TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); /* pre-condition */ assert(pi != NULL); /* check parameters */ if (lpbiIn == NULL || lpbiOut == NULL) return ICERR_BADPARAM; if (DecompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK) return ICERR_BADFORMAT; /* FIXME: cannot compress and decompress at a time! */ if (pi->bCompress) { FIXME("cannot compress and decompress at same time!\n"); return ICERR_ERROR; } if (pi->bDecompress) DecompressEnd(pi); rgbIn = (const RGBQUAD*)((const BYTE*)lpbiIn + lpbiIn->biSize); rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize); switch (lpbiOut->biBitCount) { case 4: case 8: pi->palette_map = (LPBYTE)LocalAlloc(LPTR, lpbiIn->biClrUsed); if (pi->palette_map == NULL) return ICERR_MEMORY; for (i = 0; i < lpbiIn->biClrUsed; i++) { pi->palette_map[i] = MSRLE32_GetNearestPaletteIndex(lpbiOut->biClrUsed, rgbOut, rgbIn[i]); } break; case 15: case 16: pi->palette_map = (LPBYTE)LocalAlloc(LPTR, lpbiIn->biClrUsed * 2); if (pi->palette_map == NULL) return ICERR_MEMORY; for (i = 0; i < lpbiIn->biClrUsed; i++) { WORD color; if (lpbiOut->biBitCount == 15) color = ((rgbIn[i].rgbRed >> 3) << 10) | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3); else color = ((rgbIn[i].rgbRed >> 3) << 11) | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3); pi->palette_map[i * 2 + 1] = color >> 8; pi->palette_map[i * 2 + 0] = color & 0xFF; }; break; case 24: case 32: pi->palette_map = (LPBYTE)LocalAlloc(LPTR, lpbiIn->biClrUsed * sizeof(RGBQUAD)); if (pi->palette_map == NULL) return ICERR_MEMORY; memcpy(pi->palette_map, rgbIn, lpbiIn->biClrUsed * sizeof(RGBQUAD)); break; }; pi->bDecompress = TRUE; return ICERR_OK;}static LRESULT Decompress(CodecInfo *pi, ICDECOMPRESS *pic, DWORD dwSize){ TRACE("(%p,%p,%lu)\n",pi,pic,dwSize); /* pre-condition */ assert(pi != NULL); /* check parameters */ if (pic == NULL) return ICERR_BADPARAM; if (pic->lpbiInput == NULL || pic->lpInput == NULL || pic->lpbiOutput == NULL || pic->lpOutput == NULL) return ICERR_BADPARAM; /* check formats */ if (! pi->bDecompress) { LRESULT hr = DecompressBegin(pi, pic->lpbiInput, pic->lpbiOutput); if (hr != ICERR_OK) return hr; } else if (DecompressQuery(pi, pic->lpbiInput, pic->lpbiOutput) != ICERR_OK) return ICERR_BADFORMAT; assert(pic->lpbiInput->biWidth == pic->lpbiOutput->biWidth); assert(pic->lpbiInput->biHeight == pic->lpbiOutput->biHeight); pic->lpbiOutput->biSizeImage = DIBWIDTHBYTES(*pic->lpbiOutput) * pic->lpbiOutput->biHeight; if (pic->lpbiInput->biBitCount == 4) return MSRLE32_DecompressRLE4(pi, pic->lpbiOutput, pic->lpInput, pic->lpOutput); else return MSRLE32_DecompressRLE8(pi, pic->lpbiOutput, pic->lpInput, pic->lpOutput);}static LRESULT DecompressEnd(CodecInfo *pi){ TRACE("(%p)\n",pi); /* pre-condition */ assert(pi != NULL); pi->bDecompress = FALSE; if (pi->palette_map != NULL) { LocalFree((HLOCAL)pi->palette_map); pi->palette_map = NULL; } return ICERR_OK;}static LRESULT DecompressGetPalette(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut){ int size; TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); /* pre-condition */ assert(pi != NULL); /* check parameters */ if (lpbiIn == NULL || lpbiOut == NULL) return ICERR_BADPARAM; if (DecompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK) return ICERR_BADFORMAT; if (lpbiOut->biBitCount > 8) return ICERR_ERROR; if (lpbiIn->biBitCount <= 8) { if (lpbiIn->biClrUsed > 0) size = lpbiIn->biClrUsed; else size = (1 << lpbiIn->biBitCount); lpbiOut->biClrUsed = size; memcpy((LPBYTE)lpbiOut + lpbiOut->biSize, (const BYTE*)lpbiIn + lpbiIn->biSize, size * sizeof(RGBQUAD)); } /* else could never occur ! */ return ICERR_OK;}/* DriverProc - entry point for an installable driver */LRESULT CALLBACK MSRLE32_DriverProc(DWORD dwDrvID, HDRVR hDrv, UINT uMsg, LPARAM lParam1, LPARAM lParam2){ CodecInfo *pi = (CodecInfo*)dwDrvID; TRACE("(%p,%p,0x%04X,0x%08lX,0x%08lX)\n", (LPVOID)dwDrvID, (LPVOID)hDrv, uMsg, lParam1, lParam2); switch (uMsg) { /* standard driver messages */ case DRV_LOAD: return DRVCNF_OK; case DRV_OPEN: if (lParam2 == 0) return (LRESULT)0xFFFF0000; else return (LRESULT)Open((ICOPEN*)lParam2); case DRV_CLOSE: if (dwDrvID != 0xFFFF0000 && (LPVOID)dwDrvID != NULL) Close(pi); return DRVCNF_OK; case DRV_ENABLE: case DRV_DISABLE: return DRVCNF_OK; case DRV_FREE: return DRVCNF_OK; case DRV_QUERYCONFIGURE: return DRVCNF_CANCEL; /* FIXME */ case DRV_CONFIGURE: return DRVCNF_OK; /* FIXME */ case DRV_INSTALL: case DRV_REMOVE: return DRVCNF_OK; /* installable compression manager messages */ case ICM_CONFIGURE: FIXME("ICM_CONFIGURE (%ld)\n",lParam1); if (lParam1 == -1) return ICERR_UNSUPPORTED; /* FIXME */ else return Configure(pi, (HWND)lParam1); case ICM_ABOUT: if (lParam1 == -1) return ICERR_OK; else return About(pi, (HWND)lParam1); case ICM_GETSTATE: case ICM_SETSTATE: return 0; /* no state */ case ICM_GETINFO: return GetInfo(pi, (ICINFO*)lParam1, (DWORD)lParam2); case ICM_GETDEFAULTQUALITY: if ((LPVOID)lParam1 != NULL) { *((LPDWORD)lParam1) = MSRLE32_DEFAULTQUALITY; return ICERR_OK; } break; case ICM_GETQUALITY: if ((LPVOID)lParam1 != NULL) { *((LPDWORD)lParam1) = pi->dwQuality; return ICERR_OK; } break; case ICM_SETQUALITY: return SetQuality(pi, *(LPLONG)lParam1); break; case ICM_COMPRESS_GET_FORMAT: return CompressGetFormat(pi, (LPCBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); case ICM_COMPRESS_GET_SIZE: return CompressGetSize(pi, (LPCBITMAPINFOHEADER)lParam1, (LPCBITMAPINFOHEADER)lParam2); case ICM_COMPRESS_QUERY: return CompressQuery(pi, (LPCBITMAPINFOHEADER)lParam1, (LPCBITMAPINFOHEADER)lParam2); case ICM_COMPRESS_BEGIN: return CompressBegin(pi, (LPCBITMAPINFOHEADER)lParam1, (LPCBITMAPINFOHEADER)lParam2); case ICM_COMPRESS: return Compress(pi, (ICCOMPRESS*)lParam1, (DWORD)lParam2); case ICM_COMPRESS_END: return CompressEnd(pi); case ICM_DECOMPRESS_GET_FORMAT: return DecompressGetFormat(pi, (LPCBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); case ICM_DECOMPRESS_QUERY: return DecompressQuery(pi, (LPCBITMAPINFOHEADER)lParam1, (LPCBITMAPINFOHEADER)lParam2); case ICM_DECOMPRESS_BEGIN: return DecompressBegin(pi, (LPCBITMAPINFOHEADER)lParam1, (LPCBITMAPINFOHEADER)lParam2); case ICM_DECOMPRESS: return Decompress(pi, (ICDECOMPRESS*)lParam1, (DWORD)lParam2); case ICM_DECOMPRESS_END: return DecompressEnd(pi); case ICM_DECOMPRESS_SET_PALETTE: FIXME("(...) -> SetPalette(%p,%p,%p): stub!\n", pi, (LPVOID)lParam1, (LPVOID)lParam2); return ICERR_UNSUPPORTED; case ICM_DECOMPRESS_GET_PALETTE: return DecompressGetPalette(pi, (LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); case ICM_GETDEFAULTKEYFRAMERATE: if ((LPVOID)lParam1 != NULL) *(LPDWORD)lParam1 = 15; return ICERR_OK; default: if (uMsg < DRV_USER) return DefDriverProc(dwDrvID, hDrv, uMsg, lParam1, lParam2); else FIXME("Unknown message uMsg=0x%08X lParam1=0x%08lX lParam2=0x%08lX\n",uMsg,lParam1,lParam2); }; return ICERR_UNSUPPORTED;}/* DllMain - library initialization code */BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved){ TRACE("(%p,%ld,%p)\n",(LPVOID)hModule,dwReason,lpReserved); switch (dwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hModule); MSRLE32_hModule = hModule; break; case DLL_PROCESS_DETACH: break; }; return TRUE;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?