Re: libmng data-push mechanism(s)
"Gerard Juyn" <gjuyn-qWit8jRvyhVmR6Xm/[email protected]> Fri, 9 Apr 2004 09:48:06 +0100
| Newsgroups | gmane.comp.graphics.mng.general |
|---|---|
| Message-ID | <40767156.1903.3FD8E8@localhost> |
> how does libpng work on this point? I haven't a clue.... > But how I understand the mozilla source ... we need to read out the > buffer every round ... but why we don't let read libmng the next > (<=)1024 bytes in hits own buffer if mng_display_resume is called. It > now reads also in 1024 Byte parts in the own buffer? That's because you (or rather tor) have turned on suspension mode. In this way libmng will keep an internal 32K buffer and reads 1K blocks at a time. So this is contrarary to what I said earlier about alwasy reading the 4-byte length and then the chunk, 4byte length, next chunk,etc. It is still doing that internally but there's an extra (relatively small) buffer in between. > Also if you start with mng_read then mng_read_resume always reads more > from stream and then you also can do mng_display to start displaying. > But I wan't displaying while file is read from web :-) (And also in this > way I don't know if the file in stream have ended or the buffer isn't > filled enough and so I don't know if I can call mng_display) In Mozilla I'd keep to the read&display at the same time. So to speak, because it's obviously not doing it at exactly the same time but interspersed. Which is exactly why it's so freakish complicated :( The mechanism I'm proposing, and that Ralph has extended on with a "release" callback (which is a brilliant idea btw!) will do everything you need: mnt_retcode libmng_read_pushdata (mng_handle hHandle, mng_ptr pData, mng_size_t iLength, mng_bool bTakeownership); mng_retcode libmng_read_pushchunk (mng_handle hHandle, mng_ptr pChunk, mng_size_t iLength, mng_bool bTakeownership); typedef void (*mng_releasedata) (mng_ptr pUserdata, mng_ptr pData, mng_size_t iLength); mng_retcode mng_setcb_releasedata (mng_handle hHandle, mng_releasedata fProc); The first function is used with arbitrary blocks of data streaming in. The second is specific for where the encompassing decoder already knows it's dealing with chunks (eg. the length and optionally crc are already processed; crc processing inside libmng is now decided by the libmng_set_crcmode() call; this is true for both methods *and* when using the pull mechanism!). So data-wise the only real difference is that with the second function the data *does not* hold the chunk-length value. I've split them up because libmng can process the second type much easier ;) In theory one could use both methods, but internally libmng will first deplete the 'chunk' buffer and then the 'data' buffer, so things could potentially get mixed up. Eg DON'T use both. If bTakeownership == MNG_TRUE, libmng will keep the pointer/length and disperse the buffer when it's been processed completely. If the third function was used to set a specific callback for this purpose that will be used, otherwise the default freeing mechanism will be called (which may in turn resort to a callback!). If bTakeownership == MNG_FALSE, libmng will create a new buffer and copy the provided contents across (and obviously will automatically free the created buffer once processed). I think I'll leave the current mechanism as-is, which means even using one of the push mechanisms, you still have to supply a readdata() callback. This will be called when all internally buffered data has been processed. But this callback can just simply always return '0 bytes read', in which case libmng will fall back into the normal needmoredata wait-state. Once you've received more data and pushed it in, you can call display_resume() as usual. Alex, in the push mode, you'll have to turn suspension mode off, or better said *don't* turn it on (the default is off). The whole idea with that becomes moot with this mechanism, and would just complicate things too much. Gerard ps. some nasty tricks become available too... a regular decoder using the normal pull mechanism could actually use the push calls to insert data at any given moment without changing the input-stream. It would require some clever timing, but it's possible. Say you always want to add the same BACK chunk if none is supplied, you'd call pushchunk() during the processheader() callback with a properly formatted BACK chunk (without the length but with crc; if you're processing crc's...), et voila! And I'm sure smarter people than me can come up with lots of other ideas....:) -- Send the message body "help" to [email protected]