示例#1
0
static LPVOID AVIFILE_ReadFrame(IAVIEditStreamImpl* const This,
                                PAVISTREAM pstream, LONG pos)
{
  PGETFRAME pg;

  TRACE("(%p,%p,%d)\n",This,pstream,pos);

  if (pstream == NULL)
    return NULL;

  /* if stream changes make sure that only palette changes */
  if (This->pCurStream != pstream) {
    pg = AVIStreamGetFrameOpen(pstream, NULL);
    if (pg == NULL)
      return NULL;
    if (This->pg != NULL) {
      if (IGetFrame_SetFormat(pg, This->lpFrame, NULL, 0, 0, -1, -1) != S_OK) {
        AVIStreamGetFrameClose(pg);
        ERR(": IGetFrame_SetFormat failed\n");
        return NULL;
      }
      AVIStreamGetFrameClose(This->pg);
    }
    This->pg         = pg;
    This->pCurStream = pstream;
  }

  /* now get the decompressed frame */
  This->lpFrame = AVIStreamGetFrame(This->pg, pos);
  if (This->lpFrame != NULL)
    This->sInfo.dwSuggestedBufferSize = This->lpFrame->biSizeImage;

  return This->lpFrame;
}
示例#2
0
文件: getframe.c 项目: Jactry/wine
static LPVOID  WINAPI IGetFrame_fnGetFrame(IGetFrame *iface, LONG lPos)
{
  IGetFrameImpl *This = impl_from_IGetFrame(iface);

  LONG readBytes;
  LONG readSamples;

  TRACE("(%p,%d)\n", iface, lPos);

  /* We don't want negative start values! -- marks invalid buffer content */
  if (lPos < 0)
    return NULL;

  /* check state */
  if (This->pStream == NULL)
    return NULL;
  if (This->lpInFormat == NULL)
    return NULL;

  /* Could stream have changed? */
  if (! This->bFixedStream) {
    AVISTREAMINFOW sInfo;

    IAVIStream_Info(This->pStream, &sInfo, sizeof(sInfo));

    if (sInfo.dwEditCount != This->dwEditCount) {
      This->dwEditCount   = sInfo.dwEditCount;
      This->lCurrentFrame = -1;
    }

    if (sInfo.dwFormatChangeCount != This->dwFormatChangeCount) {
      /* stream has changed */
      if (This->lpOutFormat != NULL) {
	BITMAPINFOHEADER bi;

	bi = *This->lpOutFormat;
	AVIFILE_CloseCompressor(This);

	if (FAILED(IGetFrame_SetFormat(iface, &bi, NULL, 0, 0, -1, -1))) {
	  if (FAILED(IGetFrame_SetFormat(iface, NULL, NULL, 0, 0, -1, -1)))
	    return NULL;
	}
      } else if (FAILED(IGetFrame_SetFormat(iface, NULL, NULL, 0, 0, -1, -1)))
	return NULL;
    }
  }

  if (lPos != This->lCurrentFrame) {
    LONG lNext = IAVIStream_FindSample(This->pStream,lPos,FIND_KEY|FIND_PREV);

    if (lNext == -1)
      return NULL; /* frame doesn't exist */
    if (lNext <= This->lCurrentFrame && This->lCurrentFrame < lPos)
      lNext = This->lCurrentFrame + 1;

    for (; lNext <= lPos; lNext++) {
      /* new format for this frame? */
      if (This->bFormatChanges) {
	IAVIStream_ReadFormat(This->pStream, lNext,
			      This->lpInFormat, &This->cbInFormat);
	if (This->lpOutFormat != NULL) {
	  if (This->lpOutFormat->biBitCount <= 8)
	    ICDecompressGetPalette(This->hic, This->lpInFormat,
				   This->lpOutFormat);
	}
      }

      /* read input frame */
      while (FAILED(AVIStreamRead(This->pStream, lNext, 1, This->lpInBuffer,
				  This->cbInBuffer, &readBytes, &readSamples))) {
	/* not enough memory for input buffer? */
	readBytes = 0;
	if (FAILED(AVIStreamSampleSize(This->pStream, lNext, &readBytes)))
	  return NULL; /* bad thing, but bad things will happen */
	if (readBytes <= 0) {
	  ERR(": IAVIStream::Read doesn't return needed bytes!\n");
	  return NULL;
	}

	/* IAVIStream::Read failed because of other reasons not buffersize? */
	if (This->cbInBuffer >= readBytes)
	  break;
	This->cbInBuffer = This->cbInFormat + readBytes;
	This->lpInFormat = HeapReAlloc(GetProcessHeap(), 0, This->lpInFormat, This->cbInBuffer);
	if (This->lpInFormat == NULL)
	  return NULL; /* out of memory */
	This->lpInBuffer = (BYTE*)This->lpInFormat + This->cbInFormat;
      }

      if (readSamples != 1) {
	ERR(": no frames read\n");
	return NULL;
      }
      if (readBytes != 0) {
	This->lpInFormat->biSizeImage = readBytes;

	/* nothing to decompress? */
	if (This->hic == NULL) {
	  This->lCurrentFrame = lPos;
	  return This->lpInFormat;
	}

	if (This->bResize) {
	  ICDecompressEx(This->hic,0,This->lpInFormat,This->lpInBuffer,0,0,
			 This->lpInFormat->biWidth,This->lpInFormat->biHeight,
			 This->lpOutFormat,This->lpOutBuffer,This->x,This->y,
			 This->dx,This->dy);
	} else {
	  ICDecompress(This->hic, 0, This->lpInFormat, This->lpInBuffer,
		       This->lpOutFormat, This->lpOutBuffer);
	}
      }
    } /* for (lNext < lPos) */
  } /* if (This->lCurrentFrame != lPos) */

  return (This->hic == NULL ? This->lpInFormat : This->lpOutFormat);
}