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 + -
显示快捷键?