msrle32.c
来自「Wine-20031016」· C语言 代码 · 共 1,915 行 · 第 1/4 页
C
1,915 行
} else { BYTE b1 = pi->palette_map[(code1 >> 4) * 4 + 0]; BYTE g1 = pi->palette_map[(code1 >> 4) * 4 + 1]; BYTE r1 = pi->palette_map[(code1 >> 4) * 4 + 2]; BYTE b2 = pi->palette_map[(code1 & 0x0F) * 4 + 0]; BYTE g2 = pi->palette_map[(code1 & 0x0F) * 4 + 1]; BYTE r2 = pi->palette_map[(code1 & 0x0F) * 4 + 2]; for (i = 0; i < code0; i++) { if ((i & 1) == 0) { lpOut[pixel_ptr + 0] = b1; lpOut[pixel_ptr + 1] = g1; lpOut[pixel_ptr + 2] = r1; } else { lpOut[pixel_ptr + 0] = b2; lpOut[pixel_ptr + 1] = g2; lpOut[pixel_ptr + 2] = r2; } pixel_ptr += bytes_per_pixel; } } } } while (! bEndFlag); return ICERR_OK;}static LRESULT MSRLE32_DecompressRLE8(CodecInfo *pi, LPCBITMAPINFOHEADER lpbi, LPBYTE lpIn, LPBYTE lpOut){ int bytes_per_pixel; int line_size; int pixel_ptr = 0; BOOL bEndFlag = FALSE; assert(pi != NULL); assert(lpbi != NULL && lpbi->biCompression == BI_RGB); assert(lpIn != NULL && lpOut != NULL); bytes_per_pixel = (lpbi->biBitCount + 1) / 8; line_size = DIBWIDTHBYTES(*lpbi); do { BYTE code0, code1; code0 = *lpIn++; code1 = *lpIn++; if (code0 == 0) { int extra_byte; switch (code1) { case 0: /* EOL - end of line */ pixel_ptr = 0; lpOut += line_size; break; case 1: /* EOI - end of image */ bEndFlag = TRUE; break; case 2: /* skip */ pixel_ptr += *lpIn++ * bytes_per_pixel; lpOut += *lpIn++ * line_size; if (pixel_ptr >= lpbi->biWidth * bytes_per_pixel) { pixel_ptr = 0; lpOut += line_size; } break; default: /* absolute mode */ if (pixel_ptr/bytes_per_pixel + code1 > lpbi->biWidth) { WARN("aborted absolute: (%d=%d/%d+%d) > %ld\n",pixel_ptr/bytes_per_pixel + code1,pixel_ptr,bytes_per_pixel,code1,lpbi->biWidth); return ICERR_ERROR; } extra_byte = code1 & 0x01; code0 = code1; while (code0--) { code1 = *lpIn++; if (bytes_per_pixel == 1) { lpOut[pixel_ptr] = pi->palette_map[code1]; } else if (bytes_per_pixel == 2) { lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 2 + 0]; lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 2 + 1]; } else { lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0]; lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1]; lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2]; } pixel_ptr += bytes_per_pixel; } /* if the RLE code is odd, skip a byte in the stream */ if (extra_byte) lpIn++; }; } else { /* coded mode */ if (pixel_ptr/bytes_per_pixel + code0 > lpbi->biWidth) { WARN("aborted coded: (%d=%d/%d+%d) > %ld\n",pixel_ptr/bytes_per_pixel + code1,pixel_ptr,bytes_per_pixel,code1,lpbi->biWidth); return ICERR_ERROR; } if (bytes_per_pixel == 1) { code1 = pi->palette_map[code1]; while (code0--) lpOut[pixel_ptr++] = code1; } else if (bytes_per_pixel == 2) { BYTE hi = pi->palette_map[code1 * 2 + 0]; BYTE lo = pi->palette_map[code1 * 2 + 1]; while (code0--) { lpOut[pixel_ptr + 0] = hi; lpOut[pixel_ptr + 1] = lo; pixel_ptr += bytes_per_pixel; } } else { BYTE r = pi->palette_map[code1 * 4 + 2]; BYTE g = pi->palette_map[code1 * 4 + 1]; BYTE b = pi->palette_map[code1 * 4 + 0]; while (code0--) { lpOut[pixel_ptr + 0] = b; lpOut[pixel_ptr + 1] = g; lpOut[pixel_ptr + 2] = r; pixel_ptr += bytes_per_pixel; } } } } while (! bEndFlag); return ICERR_OK;}/*****************************************************************************/static CodecInfo* Open(LPICOPEN icinfo){ CodecInfo* pi = NULL; if (icinfo == NULL) { TRACE("(NULL)\n"); return (LPVOID)0xFFFF0000; } TRACE("(%p = {%lu,0x%08lX(%4.4s),0x%08lX(%4.4s),0x%lX,0x%lX,...})\n", icinfo, icinfo->dwSize, icinfo->fccType, (char*)&icinfo->fccType, icinfo->fccHandler, (char*)&icinfo->fccHandler, icinfo->dwVersion,icinfo->dwFlags); if (icinfo->fccType != ICTYPE_VIDEO) return NULL; switch (icinfo->fccHandler) { case FOURCC_RLE: case FOURCC_RLE4: case FOURCC_RLE8: case FOURCC_MRLE: break; case mmioFOURCC('m','r','l','e'): icinfo->fccHandler = FOURCC_MRLE; break; default: WARN("unknown FOURCC = 0x%08lX(%4.4s) !\n", icinfo->fccHandler,(char*)&icinfo->fccHandler); return NULL; } pi = (CodecInfo*)LocalAlloc(LPTR, sizeof(CodecInfo)); if (pi != NULL) { pi->fccHandler = icinfo->fccHandler; pi->bCompress = FALSE; pi->dwQuality = MSRLE32_DEFAULTQUALITY; pi->nPrevFrame = -1; pi->pPrevFrame = pi->pCurFrame = NULL; pi->bDecompress = FALSE; pi->palette_map = NULL; } icinfo->dwError = (pi != NULL ? ICERR_OK : ICERR_MEMORY); return pi;}static LRESULT Close(CodecInfo *pi){ TRACE("(%p)\n", pi); /* pre-condition */ assert(pi != NULL); if (pi->pPrevFrame != NULL || pi->pCurFrame != NULL) CompressEnd(pi); LocalFree((HLOCAL)pi); return 1;}static LRESULT GetInfo(CodecInfo *pi, ICINFO *icinfo, DWORD dwSize){ /* pre-condition */ assert(pi != NULL); /* check parameters */ if (icinfo == NULL) return sizeof(ICINFO); if (dwSize < sizeof(ICINFO)) return 0; icinfo->dwSize = sizeof(ICINFO); icinfo->fccType = streamtypeVIDEO; icinfo->fccHandler = (pi != NULL ? pi->fccHandler : FOURCC_MRLE); icinfo->dwFlags = VIDCF_QUALITY | VIDCF_TEMPORAL | VIDCF_CRUNCH | VIDCF_FASTTEMPORALC; icinfo->dwVersion = MSRLE32_VERSION; icinfo->dwVersionICM = 0x01040000; /* Version 1.4 build 0 */ LoadWideString(IDS_NAME, icinfo->szName, sizeof(icinfo->szName)); LoadWideString(IDS_DESCRIPTION, icinfo->szDescription, sizeof(icinfo->szDescription)); return sizeof(ICINFO);}static LRESULT SetQuality(CodecInfo *pi, LONG lQuality){ /* pre-condition */ assert(pi != NULL); if (lQuality == -1) lQuality = MSRLE32_DEFAULTQUALITY; else if (ICQUALITY_LOW > lQuality || lQuality > ICQUALITY_HIGH) return ICERR_BADPARAM; pi->dwQuality = (DWORD)lQuality; return ICERR_OK;}static LRESULT Configure(CodecInfo *pi, HWND hWnd){ /* pre-condition */ assert(pi != NULL); /* FIXME */ return ICERR_OK;}static LRESULT About(CodecInfo *pi, HWND hWnd){ CHAR szTitle[20]; CHAR szAbout[128]; /* pre-condition */ assert(MSRLE32_hModule != 0); LoadStringA(MSRLE32_hModule, IDS_NAME, szTitle, sizeof(szTitle)); LoadStringA(MSRLE32_hModule, IDS_ABOUT, szAbout, sizeof(szAbout)); MessageBoxA(hWnd, szAbout, szTitle, MB_OK|MB_ICONINFORMATION); return ICERR_OK;}static LRESULT CompressGetFormat(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut){ LRESULT size; TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); /* pre-condition */ assert(pi != NULL); /* check parameters -- need atleast input format */ if (lpbiIn == NULL) { if (lpbiOut != NULL) return ICERR_BADPARAM; return 0; } /* handle unsupported input format */ if (CompressQuery(pi, lpbiIn, NULL) != ICERR_OK) return (lpbiOut == NULL ? ICERR_BADFORMAT : 0); assert(0 < lpbiIn->biBitCount && lpbiIn->biBitCount <= 8); switch (pi->fccHandler) { case FOURCC_RLE4: size = 1 << 4; break; case FOURCC_RLE8: size = 1 << 8; break; case FOURCC_RLE: case FOURCC_MRLE: size = (lpbiIn->biBitCount <= 4 ? 1 << 4 : 1 << 8); break; default: return ICERR_ERROR; } if (lpbiIn->biClrUsed != 0) size = lpbiIn->biClrUsed; size = sizeof(BITMAPINFOHEADER) + size * sizeof(RGBQUAD); if (lpbiOut != NULL) { lpbiOut->biSize = sizeof(BITMAPINFOHEADER); lpbiOut->biWidth = lpbiIn->biWidth; lpbiOut->biHeight = lpbiIn->biHeight; lpbiOut->biPlanes = 1; if (pi->fccHandler == FOURCC_RLE4 || lpbiIn->biBitCount <= 4) { lpbiOut->biCompression = BI_RLE4; lpbiOut->biBitCount = 4; } else { lpbiOut->biCompression = BI_RLE8; lpbiOut->biBitCount = 8; } lpbiOut->biSizeImage = MSRLE32_GetMaxCompressedSize(lpbiOut); lpbiOut->biXPelsPerMeter = lpbiIn->biXPelsPerMeter; lpbiOut->biYPelsPerMeter = lpbiIn->biYPelsPerMeter; if (lpbiIn->biClrUsed == 0) size = 1<<lpbiIn->biBitCount; else size = lpbiIn->biClrUsed; lpbiOut->biClrUsed = min(size, 1 << lpbiOut->biBitCount); lpbiOut->biClrImportant = 0; memcpy((LPBYTE)lpbiOut + lpbiOut->biSize, (const BYTE*)lpbiIn + lpbiIn->biSize, lpbiOut->biClrUsed * sizeof(RGBQUAD)); return ICERR_OK; } else return size;}static LRESULT CompressGetSize(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER lpbiOut){ /* pre-condition */ assert(pi != NULL); TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); /* check parameter -- need atleast one format */ if (lpbiIn == NULL && lpbiOut == NULL) return 0; /* check if the given format is supported */ if (CompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK) return 0; /* the worst case is coding the complete image in absolute mode. */ if (lpbiIn) return MSRLE32_GetMaxCompressedSize(lpbiIn); else return MSRLE32_GetMaxCompressedSize(lpbiOut);}static LRESULT CompressQuery(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER 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 (!isSupportedDIB(lpbiIn)) return ICERR_BADFORMAT; /* for 4-bit need an even width */ if (lpbiIn->biBitCount <= 4 && (lpbiIn->biWidth % 2)) return ICERR_BADFORMAT; if (pi->fccHandler == FOURCC_RLE4 && lpbiIn->biBitCount > 4) return ICERR_UNSUPPORTED; else if (lpbiIn->biBitCount > 8) return ICERR_UNSUPPORTED; } /* check output format if given */ if (lpbiOut != NULL) { if (!isSupportedMRLE(lpbiOut)) return ICERR_BADFORMAT; if (lpbiIn != NULL) { if (lpbiIn->biWidth != lpbiOut->biWidth) return ICERR_UNSUPPORTED; if (lpbiIn->biHeight != lpbiOut->biHeight) return ICERR_UNSUPPORTED; if (lpbiIn->biBitCount > lpbiOut->biBitCount) return ICERR_UNSUPPORTED; } } return ICERR_OK;}static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPCBITMAPINFOHEADER lpbiOut){ const RGBQUAD *rgbIn; const RGBQUAD *rgbOut; UINT i; size_t size; TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); /* pre-condition */ assert(pi != NULL); /* check parameters -- need both formats */ if (lpbiIn == NULL || lpbiOut == NULL) return ICERR_BADPARAM; /* And both must be supported */ if (CompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK) return ICERR_BADFORMAT; /* FIXME: cannot compress and decompress at same time! */ if (pi->bDecompress) { FIXME("cannot compress and decompress at same time!\n"); return ICERR_ERROR; } if (pi->bCompress) CompressEnd(pi); size = WIDTHBYTES(lpbiOut->biWidth * 16) / 2 * lpbiOut->biHeight; pi->pPrevFrame = (LPWORD)GlobalAllocPtr(GPTR, size * sizeof(WORD)); if (pi->pPrevFrame == NULL) return ICERR_MEMORY; pi->pCurFrame = (LPWORD)GlobalAllocPtr(GPTR, size * sizeof(WORD)); if (pi->pCurFrame == NULL) { CompressEnd(pi); return ICERR_MEMORY; } pi->nPrevFrame = -1; pi->bCompress = TRUE; 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) { CompressEnd(pi); return ICERR_MEMORY; } for (i = 0; i < lpbiIn->biClrUsed; i++) { pi->palette_map[i] = MSRLE32_GetNearestPaletteIndex(lpbiOut->biClrUsed, rgbOut, rgbIn[i]); } break; }; return ICERR_OK;}static LRESULT Compress(CodecInfo *pi, ICCOMPRESS* lpic, DWORD dwSize){ int i; TRACE("(%p,%p,%lu)\n",pi,lpic,dwSize); /* pre-condition */ assert(pi != NULL); /* check parameters */ if (lpic == NULL || dwSize < sizeof(ICCOMPRESS)) return ICERR_BADPARAM; if (!lpic->lpbiOutput || !lpic->lpOutput || !lpic->lpbiInput || !lpic->lpInput)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?