static LONG WINAPI IAVIStream_fnFindSample(IAVIStream *iface, LONG pos, LONG flags) { IAVIFileImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%d,0x%08X)\n",iface,pos,flags); /* Do we have data? */ if (This->lpFormat == NULL) return -1; /* We don't have an index */ if (flags & FIND_INDEX) return -1; if (flags & FIND_FROM_START) { pos = This->sInfo.dwStart; flags &= ~(FIND_FROM_START|FIND_PREV); flags |= FIND_NEXT; } if (flags & FIND_FORMAT) { if ((flags & FIND_NEXT) && pos > 0) pos = -1; else pos = 0; } if ((flags & FIND_RET) == FIND_LENGTH || (flags & FIND_RET) == FIND_SIZE) return This->sInfo.dwSampleSize; if ((flags & FIND_RET) == FIND_OFFSET) return This->ckData.dwDataOffset + pos * This->sInfo.dwSampleSize; return pos; }
static LONG WINAPI IEditAVIStream_fnFindSample(IAVIStream*iface,LONG pos, LONG flags) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); PAVISTREAM stream; DWORD streamPos, streamNr; TRACE("(%p,%d,0x%08X)\n",iface,pos,flags); if (flags & FIND_FROM_START) pos = (LONG)This->sInfo.dwStart; /* outside of stream? */ if (pos < (LONG)This->sInfo.dwStart || (LONG)This->sInfo.dwStart + (LONG)This->sInfo.dwLength <= pos) return -1; /* map our position to a stream and position in it */ if (AVIFILE_FindStreamInTable(This, pos, &stream, &streamPos, &streamNr, TRUE) != S_OK) return -1; /* doesn't exist */ if (This->bDecompress) { /* only one stream -- format changes only at start */ if (flags & FIND_FORMAT) return (flags & FIND_NEXT ? -1 : 0); /* FIXME: map positions back to us */ return IAVIStream_FindSample(stream, streamPos, flags); } else { /* assume change of format every frame */ return pos; } }
static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream *iface, LONG pos, void *format, LONG *formatsize) { IAVIFileImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%d,%p,%p)\n", iface, pos, format, formatsize); if (formatsize == NULL) return AVIERR_BADPARAM; /* only interested in needed buffersize? */ if (format == NULL || *formatsize <= 0) { *formatsize = This->cbFormat; return AVIERR_OK; } /* copy initial format (only as much as will fit) */ memcpy(format, This->lpFormat, min(*formatsize, This->cbFormat)); if (*formatsize < This->cbFormat) { *formatsize = This->cbFormat; return AVIERR_BUFFERTOOSMALL; } *formatsize = This->cbFormat; return AVIERR_OK; }
static HRESULT WINAPI IEditAVIStream_fnCreate(IAVIStream*iface, LPARAM lParam1,LPARAM lParam2) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); if (lParam2 != 0) return AVIERR_ERROR; if (This->pStreams == NULL) { This->pStreams = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256 * sizeof(EditStreamTable)); if (This->pStreams == NULL) return AVIERR_MEMORY; This->nTableSize = 256; } if (lParam1 != 0) { IAVIStream_Info((PAVISTREAM)lParam1, &This->sInfo, sizeof(This->sInfo)); IAVIStream_AddRef((PAVISTREAM)lParam1); This->pStreams[0].pStream = (PAVISTREAM)lParam1; This->pStreams[0].dwStart = This->sInfo.dwStart; This->pStreams[0].dwLength = This->sInfo.dwLength; This->nStreams = 1; } return AVIERR_OK; }
static HRESULT WINAPI IEditAVIStream_fnSetInfo(IAVIStream*iface, AVISTREAMINFOW*info,LONG len) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); TRACE("(%p,%p,%d)\n",iface,info,len); return IAVIEditStream_SetInfo(&This->IAVIEditStream_iface,info,len); }
static HRESULT WINAPI ICMStream_fnDelete(IAVIStream *iface, LONG start, LONG samples) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%d,%d)\n", iface, start, samples); return IAVIStream_Delete(This->pStream, start, samples); }
static HRESULT WINAPI IEditAVIStream_fnDelete(IAVIStream*iface,LONG start, LONG samples) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); TRACE("(%p,%d,%d)\n",iface,start,samples); return IAVIEditStream_Cut(&This->IAVIEditStream_iface,&start,&samples,NULL); }
static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos, void *format, LONG formatsize) { IAVIFileImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%d,%p,%d)\n", iface, pos, format, formatsize); /* check parameters */ if (format == NULL || formatsize <= sizeof(PCMWAVEFORMAT)) return AVIERR_BADPARAM; /* We can only do this to an empty wave file, but ignore call * if still same format */ if (This->lpFormat != NULL) { if (formatsize != This->cbFormat || memcmp(format, This->lpFormat, formatsize) != 0) return AVIERR_UNSUPPORTED; return AVIERR_OK; } /* only support start at position 0 */ if (pos != 0) return AVIERR_UNSUPPORTED; /* Do we have write permission? */ if ((This->uMode & MMIO_RWMODE) == 0) return AVIERR_READONLY; /* get memory for format and copy it */ This->lpFormat = HeapAlloc(GetProcessHeap(), 0, formatsize); if (This->lpFormat == NULL) return AVIERR_MEMORY; This->cbFormat = formatsize; memcpy(This->lpFormat, format, formatsize); /* update info's about 'data' chunk */ This->ckData.dwDataOffset = formatsize + 7 * sizeof(DWORD); This->ckData.cksize = 0; /* for non-pcm format we need also a 'fact' chunk */ if (This->lpFormat->wFormatTag != WAVE_FORMAT_PCM) This->ckData.dwDataOffset += 3 * sizeof(DWORD); /* update stream and file info */ This->sInfo.dwSampleSize = This->lpFormat->nBlockAlign; This->sInfo.dwScale = This->lpFormat->nBlockAlign; This->sInfo.dwRate = This->lpFormat->nAvgBytesPerSec; This->sInfo.dwLength = 0; This->sInfo.dwSuggestedBufferSize = 0; return AVIERR_OK; }
static HRESULT WINAPI ICMStream_fnWriteData(IAVIStream *iface, DWORD fcc, LPVOID lp, LONG size) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,0x%08x,%p,%d)\n", iface, fcc, lp, size); assert(This->pStream != NULL); return IAVIStream_WriteData(This->pStream, fcc, lp, size); }
static HRESULT WINAPI ICMStream_fnReadData(IAVIStream *iface, DWORD fcc, LPVOID lp, LPLONG lpread) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,0x%08X,%p,%p)\n", iface, fcc, lp, lpread); assert(This->pStream != NULL); return IAVIStream_ReadData(This->pStream, fcc, lp, lpread); }
static ULONG WINAPI ICMStream_fnRelease(IAVIStream* iface) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) -> %d\n", iface, ref); if (ref == 0) { /* destruct */ if (This->pg != NULL) { AVIStreamGetFrameClose(This->pg); This->pg = NULL; } if (This->pStream != NULL) { IAVIStream_Release(This->pStream); This->pStream = NULL; } if (This->hic != NULL) { if (This->lpbiPrev != NULL) { ICDecompressEnd(This->hic); HeapFree(GetProcessHeap(), 0, This->lpbiPrev); This->lpbiPrev = NULL; This->lpPrev = NULL; } ICCompressEnd(This->hic); This->hic = NULL; } if (This->lpbiCur != NULL) { HeapFree(GetProcessHeap(), 0, This->lpbiCur); This->lpbiCur = NULL; This->lpCur = NULL; } if (This->lpbiOutput != NULL) { HeapFree(GetProcessHeap(), 0, This->lpbiOutput); This->lpbiOutput = NULL; This->cbOutput = 0; } if (This->lpbiInput != NULL) { HeapFree(GetProcessHeap(), 0, This->lpbiInput); This->lpbiInput = NULL; This->cbInput = 0; } HeapFree(GetProcessHeap(), 0, This); return 0; } /* also release reference to the nested stream */ if (This->pStream != NULL) IAVIStream_Release(This->pStream); return ref; }
static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream *iface, LONG start, LONG samples, void *buffer, LONG buffersize, DWORD flags, LONG *sampwritten, LONG *byteswritten) { IAVIFileImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%d,%d,%p,%d,0x%08X,%p,%p)\n", iface, start, samples, buffer, buffersize, flags, sampwritten, byteswritten); /* clear return parameters if given */ if (sampwritten != NULL) *sampwritten = 0; if (byteswritten != NULL) *byteswritten = 0; /* check parameters */ if (buffer == NULL && (buffersize > 0 || samples > 0)) return AVIERR_BADPARAM; /* Do we have write permission? */ if ((This->uMode & MMIO_RWMODE) == 0) return AVIERR_READONLY; /* < 0 means "append" */ if (start < 0) start = This->sInfo.dwStart + This->sInfo.dwLength; /* check buffersize -- must multiple of samplesize */ if (buffersize & ~(This->sInfo.dwSampleSize - 1)) return AVIERR_BADSIZE; /* do we have anything to write? */ if (buffer != NULL && buffersize > 0) { This->fDirty = TRUE; if (mmioSeek(This->hmmio, This->ckData.dwDataOffset + start * This->sInfo.dwSampleSize, SEEK_SET) == -1) return AVIERR_FILEWRITE; if (mmioWrite(This->hmmio, buffer, buffersize) != buffersize) return AVIERR_FILEWRITE; This->sInfo.dwLength = max(This->sInfo.dwLength, (DWORD)start + samples); This->ckData.cksize = max(This->ckData.cksize, start * This->sInfo.dwSampleSize + buffersize); /* fill out return parameters if given */ if (sampwritten != NULL) *sampwritten = samples; if (byteswritten != NULL) *byteswritten = buffersize; } return AVIERR_OK; }
static ULONG WINAPI ICMStream_fnAddRef(IAVIStream *iface) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p) -> %d\n", iface, ref); /* also add reference to the nested stream */ if (This->pStream != NULL) IAVIStream_AddRef(This->pStream); return ref; }
static HRESULT WINAPI ICMStream_fnReadFormat(IAVIStream *iface, LONG pos, LPVOID format, LONG *formatsize) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); LPBITMAPINFOHEADER lpbi; HRESULT hr; TRACE("(%p,%d,%p,%p)\n", iface, pos, format, formatsize); if (formatsize == NULL) return AVIERR_BADPARAM; if (This->pg == NULL) { hr = AVIFILE_OpenGetFrame(This); if (FAILED(hr)) return hr; } lpbi = AVIStreamGetFrame(This->pg, pos); if (lpbi == NULL) return AVIERR_MEMORY; if (This->hic == NULL) { LONG size = lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD); if (size > 0) { if (This->sInfo.dwSuggestedBufferSize < lpbi->biSizeImage) This->sInfo.dwSuggestedBufferSize = lpbi->biSizeImage; This->cbOutput = size; if (format != NULL) { if (This->lpbiOutput != NULL) memcpy(format, This->lpbiOutput, min(*formatsize, This->cbOutput)); else memcpy(format, lpbi, min(*formatsize, size)); } } } else if (format != NULL) memcpy(format, This->lpbiOutput, min(*formatsize, This->cbOutput)); if (*formatsize < This->cbOutput) hr = AVIERR_BUFFERTOOSMALL; else hr = AVIERR_OK; *formatsize = This->cbOutput; return hr; }
static HRESULT WINAPI ICMStream_fnWrite(IAVIStream *iface, LONG start, LONG samples, LPVOID buffer, LONG buffersize, DWORD flags, LPLONG sampwritten, LPLONG byteswritten) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); HRESULT hr; TRACE("(%p,%d,%d,%p,%d,0x%08X,%p,%p)\n", iface, start, samples, buffer, buffersize, flags, sampwritten, byteswritten); /* clear return parameters if given */ if (sampwritten != NULL) *sampwritten = 0; if (byteswritten != NULL) *byteswritten = 0; /* check parameters */ if (buffer == NULL && (buffersize > 0 || samples > 0)) return AVIERR_BADPARAM; if (This->sInfo.fccHandler == comptypeDIB) { /* only pass through */ flags |= AVIIF_KEYFRAME; return IAVIStream_Write(This->pStream, start, samples, buffer, buffersize, flags, sampwritten, byteswritten); } else { /* compress data before writing to pStream */ if (samples != 1 && (sampwritten == NULL && byteswritten == NULL)) return AVIERR_UNSUPPORTED; This->lCurrent = start; hr = AVIFILE_EncodeFrame(This, This->lpbiInput, buffer); if (FAILED(hr)) return hr; if (This->lLastKey == start) flags |= AVIIF_KEYFRAME; return IAVIStream_Write(This->pStream, start, samples, This->lpCur, This->lpbiCur->biSizeImage, flags, byteswritten, sampwritten); } }
static HRESULT WINAPI ICMStream_fnQueryInterface(IAVIStream *iface, REFIID refiid, LPVOID *obj) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%s,%p)\n", iface, debugstr_guid(refiid), obj); if (IsEqualGUID(&IID_IUnknown, refiid) || IsEqualGUID(&IID_IAVIStream, refiid)) { *obj = &This->IAVIStream_iface; IAVIStream_AddRef(iface); return S_OK; } return OLE_E_ENUM_NOMORE; }
static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream *iface, AVISTREAMINFOW *psi, LONG size) { IAVIFileImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%p,%d)\n", iface, psi, size); if (psi == NULL) return AVIERR_BADPARAM; if (size < 0) return AVIERR_BADSIZE; memcpy(psi, &This->sInfo, min((DWORD)size, sizeof(This->sInfo))); if ((DWORD)size < sizeof(This->sInfo)) return AVIERR_BUFFERTOOSMALL; return AVIERR_OK; }
static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream *iface, LONG start, LONG samples) { IAVIFileImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%d,%d)\n", iface, start, samples); /* check parameters */ if (start < 0 || samples < 0) return AVIERR_BADPARAM; /* Delete before start of stream? */ if ((DWORD)(start + samples) < This->sInfo.dwStart) return AVIERR_OK; /* Delete after end of stream? */ if ((DWORD)start > This->sInfo.dwLength) return AVIERR_OK; /* For the rest we need write permissions */ if ((This->uMode & MMIO_RWMODE) == 0) return AVIERR_READONLY; if ((DWORD)(start + samples) >= This->sInfo.dwLength) { /* deletion at end */ samples = This->sInfo.dwLength - start; This->sInfo.dwLength -= samples; This->ckData.cksize -= samples * This->sInfo.dwSampleSize; } else if ((DWORD)start <= This->sInfo.dwStart) { /* deletion at start */ samples = This->sInfo.dwStart - start; start = This->sInfo.dwStart; This->ckData.dwDataOffset += samples * This->sInfo.dwSampleSize; This->ckData.cksize -= samples * This->sInfo.dwSampleSize; } else { /* deletion inside stream -- needs playlist and cue's */ FIXME(": deletion inside of stream not supported!\n"); return AVIERR_UNSUPPORTED; } This->fDirty = TRUE; return AVIERR_OK; }
static HRESULT WINAPI IEditAVIStream_fnReadFormat(IAVIStream*iface,LONG pos, LPVOID format,LONG*fmtsize) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); LPBITMAPINFOHEADER lp; PAVISTREAM stream; DWORD n; HRESULT hr; TRACE("(%p,%d,%p,%p)\n",iface,pos,format,fmtsize); if (fmtsize == NULL || pos < This->sInfo.dwStart || This->sInfo.dwStart + This->sInfo.dwLength <= pos) return AVIERR_BADPARAM; /* find stream corresponding to position */ hr = AVIFILE_FindStreamInTable(This, pos, &stream, &n, NULL, FALSE); if (FAILED(hr)) return hr; if (! This->bDecompress) return IAVIStream_ReadFormat(stream, n, format, fmtsize); lp = AVIFILE_ReadFrame(This, stream, n); if (lp == NULL) return AVIERR_ERROR; if (lp->biBitCount <= 8) { n = (lp->biClrUsed > 0 ? lp->biClrUsed : 1 << lp->biBitCount); n *= sizeof(RGBQUAD); } else n = 0; n += lp->biSize; memcpy(format, lp, min((LONG)n, *fmtsize)); hr = ((LONG)n > *fmtsize ? AVIERR_BUFFERTOOSMALL : AVIERR_OK); *fmtsize = n; return hr; }
static HRESULT WINAPI IEditAVIStream_fnReadData(IAVIStream*iface,DWORD fcc, LPVOID lp,LONG *lpread) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); DWORD n; TRACE("(%p,0x%08X,%p,%p)\n",iface,fcc,lp,lpread); /* check parameters */ if (lp == NULL || lpread == NULL) return AVIERR_BADPARAM; /* simply ask every stream and return the first block found */ for (n = 0; n < This->nStreams; n++) { HRESULT hr = IAVIStream_ReadData(This->pStreams[n].pStream,fcc,lp,lpread); if (SUCCEEDED(hr)) return hr; } *lpread = 0; return AVIERR_NODATA; }
static LONG WINAPI ICMStream_fnFindSample(IAVIStream *iface, LONG pos, LONG flags) { IAVIStreamImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%d,0x%08X)\n",iface,pos,flags); if (flags & FIND_FROM_START) { pos = This->sInfo.dwStart; flags &= ~(FIND_FROM_START|FIND_PREV); flags |= FIND_NEXT; } if (flags & FIND_RET) WARN(": FIND_RET flags will be ignored!\n"); if (flags & FIND_KEY) { if (This->hic == NULL) return pos; /* we decompress so every frame is a keyframe */ if (flags & FIND_PREV) { /* need to read old or new frames? */ if (This->lLastKey <= pos || pos < This->lCurrent) IAVIStream_Read(iface, pos, 1, NULL, 0, NULL, NULL); return This->lLastKey; } } else if (flags & FIND_ANY) { return pos; /* We really don't know, reread is too expensive, so guess. */ } else if (flags & FIND_FORMAT) { if (flags & FIND_PREV) return 0; } return -1; }
static HRESULT WINAPI IAVIStream_fnRead(IAVIStream *iface, LONG start, LONG samples, void *buffer, LONG buffersize, LONG *bytesread, LONG *samplesread) { IAVIFileImpl *This = impl_from_IAVIStream(iface); TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", iface, start, samples, buffer, buffersize, bytesread, samplesread); /* clear return parameters if given */ if (bytesread != NULL) *bytesread = 0; if (samplesread != NULL) *samplesread = 0; /* positions without data */ if (start < 0 || (DWORD)start > This->sInfo.dwLength) return AVIERR_OK; /* check samples */ if (samples < 0) samples = 0; if (buffersize > 0) { if (samples > 0) samples = min((DWORD)samples, buffersize / This->sInfo.dwSampleSize); else samples = buffersize / This->sInfo.dwSampleSize; } /* limit to end of stream */ if ((DWORD)(start + samples) > This->sInfo.dwLength) samples = This->sInfo.dwLength - start; /* request only the sizes? */ if (buffer == NULL || buffersize <= 0) { /* then I need at least one parameter for it */ if (bytesread == NULL && samplesread == NULL) return AVIERR_BADPARAM; if (bytesread != NULL) *bytesread = samples * This->sInfo.dwSampleSize; if (samplesread != NULL) *samplesread = samples; return AVIERR_OK; } /* nothing to read? */ if (samples == 0) return AVIERR_OK; /* Can I read at least one sample? */ if ((DWORD)buffersize < This->sInfo.dwSampleSize) return AVIERR_BUFFERTOOSMALL; buffersize = samples * This->sInfo.dwSampleSize; if (mmioSeek(This->hmmio, This->ckData.dwDataOffset + start * This->sInfo.dwSampleSize, SEEK_SET) == -1) return AVIERR_FILEREAD; if (mmioRead(This->hmmio, buffer, buffersize) != buffersize) return AVIERR_FILEREAD; /* fill out return parameters if given */ if (bytesread != NULL) *bytesread = buffersize; if (samplesread != NULL) *samplesread = samples; return AVIERR_OK; }
static HRESULT WINAPI IEditAVIStream_fnQueryInterface(IAVIStream*iface, REFIID refiid,LPVOID*obj) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); return IAVIEditStream_QueryInterface(&This->IAVIEditStream_iface,refiid,obj); }
static ULONG WINAPI IEditAVIStream_fnAddRef(IAVIStream*iface) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); return IAVIEditStream_AddRef(&This->IAVIEditStream_iface); }
static ULONG WINAPI IEditAVIStream_fnRelease(IAVIStream*iface) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); return IAVIEditStream_Release(&This->IAVIEditStream_iface); }
static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream *iface, DWORD fcc, void *lp, LONG *lpread) { IAVIFileImpl *This = impl_from_IAVIStream(iface); return IAVIFile_ReadData(&This->IAVIFile_iface, fcc, lp, lpread); }
static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) { IAVIFileImpl *This = impl_from_IAVIStream(iface); return IUnknown_Release(This->outer_unk); }
static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream *iface, REFIID riid, void **ret_iface) { IAVIFileImpl *This = impl_from_IAVIStream(iface); return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface); }
static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream *iface, DWORD fcc, void *lp, LONG size) { IAVIFileImpl *This = impl_from_IAVIStream(iface); return IAVIFile_WriteData(&This->IAVIFile_iface, fcc, lp, size); }
static HRESULT WINAPI IEditAVIStream_fnRead(IAVIStream*iface,LONG start, LONG samples,LPVOID buffer, LONG buffersize,LONG*bytesread, LONG*samplesread) { IAVIEditStreamImpl *This = impl_from_IAVIStream( iface ); PAVISTREAM stream; DWORD streamPos, streamNr; LONG readBytes, readSamples, count; HRESULT hr; TRACE("(%p,%d,%d,%p,%d,%p,%p) -- 0x%08X\n",iface,start,samples, buffer,buffersize,bytesread,samplesread,This->sInfo.fccType); /* check parameters */ if (bytesread != NULL) *bytesread = 0; if (samplesread != NULL) *samplesread = 0; if (buffersize < 0) return AVIERR_BADSIZE; if ((DWORD)start < This->sInfo.dwStart || This->sInfo.dwStart + This->sInfo.dwLength < (DWORD)start) return AVIERR_BADPARAM; if (! This->bDecompress) { /* audio like data -- sample-based */ do { if (samples == 0) return AVIERR_OK; /* nothing at all or already done */ if (FAILED(AVIFILE_FindStreamInTable(This, start, &stream, &streamPos, &streamNr, FALSE))) return AVIERR_ERROR; /* limit to end of the stream */ count = samples; if (streamPos + count > EditStreamEnd(This, streamNr)) count = EditStreamEnd(This, streamNr) - streamPos; hr = IAVIStream_Read(stream, streamPos, count, buffer, buffersize, &readBytes, &readSamples); if (FAILED(hr)) return hr; if (readBytes == 0 && readSamples == 0 && count != 0) return AVIERR_FILEREAD; /* for bad stream implementations */ if (samplesread != NULL) *samplesread += readSamples; if (bytesread != NULL) *bytesread += readBytes; if (buffer != NULL) { buffer = ((LPBYTE)buffer)+readBytes; buffersize -= readBytes; } start += count; samples -= count; } while (This->sInfo.dwStart + This->sInfo.dwLength > start); } else { /* video like data -- frame-based */ LPBITMAPINFOHEADER lp; if (samples == 0) return AVIERR_OK; if (FAILED(AVIFILE_FindStreamInTable(This, start, &stream, &streamPos, &streamNr, FALSE))) return AVIERR_ERROR; lp = AVIFILE_ReadFrame(This, stream, streamPos); if (lp == NULL) return AVIERR_ERROR; if (buffer != NULL) { /* need size of format to skip */ if (lp->biBitCount <= 8) { count = lp->biClrUsed > 0 ? lp->biClrUsed : 1 << lp->biBitCount; count *= sizeof(RGBQUAD); } else count = 0; count += lp->biSize; if (buffersize < lp->biSizeImage) return AVIERR_BUFFERTOOSMALL; memcpy(buffer, (LPBYTE)lp + count, lp->biSizeImage); } if (bytesread != NULL) *bytesread = lp->biSizeImage; if (samplesread != NULL) *samplesread = 1; } return AVIERR_OK; }