Page 1 of 1
Detection af aan jpeg in a TMemorystream for a RichView
Posted: Tue Apr 29, 2008 2:57 pm
by jp
How can ik locate a jpeg in a TMemoryStream. I have to copy part of this stream to be shown in a RichView.
I copy this part op basis of a token - $$name$$ content $$. But if there is a jpeg in this part of the stream there are a big chance that also ´$$´ are in the binery of the jpeg.
I looking for a way to detect the start en end of the jpeg. I thoufht that I had found it - That the jpeg always begin with "TJPEGImage" en always end wit "3 0 0 0 0". But today I get all "1 0 0 0 0".
Thus my questions is - Is the "TJPEGImage" and "1 0 0 0 0" something that RichView insert of is that from the TJPEG (Graphic class)?
Or have someone another suggestion?
JP
Posted: Tue Apr 29, 2008 3:23 pm
by Sergey Tkachenko
It is saved by TRichView in RVF.
See
http://www.trichview.com/help/index.htm ... ation.html
The line "1 0 0 0 0" belongs to some text item, not to picture item.
The line containing picture starts from -3 (rvsPicture).
The next line is a picture name (usually empty)
The next line is a graphic class (for jpegs, it is TJPEGImage).
Then binary data follows (4 byte size, then jpeg data).
But if you extracting part of data basing on substrings, what will happen if the user types "TJPEGImage" in text?
Posted: Tue Apr 29, 2008 4:06 pm
by jp
Thanks Sergey
Your right - I have a problem if the user type in TJPEGImage. But do you se another options?
JP
Posted: Wed Apr 30, 2008 2:58 pm
by Sergey Tkachenko
Please describe what you want to implement with more details.
Posted: Tue May 06, 2008 6:59 am
by jp
Thanks Sergey
I realize that this is not a RichView problem. But if any one can help it would be appreciated very much.
I need to copy a section of a memorystream an present this in a RichView. The stream, from where I have to copy this section, is made in the richviewactions demo.
Each section start with a token like this - "$$sectionhead$$". I search for this to determent the start point and then searching for the next $$ to finding the end point of the section. That goes well as long I dont have any jpeg in the section, because the chances that in this binary representation of the jpeg you will find my token - $$ is pretty high.
Because of specific reasons I can't change the token and there for I have to search the stream for the start en end point of this (of those) jpeg(s), so I can exclude those part of the stream in my search for the end point of the section.
In short the question is: How can I search for the starting and ending point of a jpeg in a memorystream?
JP
Posted: Tue May 06, 2008 3:05 pm
by Sergey Tkachenko
'TJPEGImage' string, then line break (#13#10), then 4 bytes containing size of jpeg data, then jpeg data.
Posted: Thu May 08, 2008 3:32 pm
by jp
Tanks Sergey,
Could give me a hint how to read the size. I have tried all what I could think off but nothing works.
Code: Select all
GetMem(Buf, 4);
Source.Read(Buf[0], 4);
S := Copy(Buf, 1, 4);
But how doe get as a Integer?
JP
Posted: Thu May 08, 2008 4:44 pm
by Sergey Tkachenko
var Size: Integer;
Source.ReadBuffer(Size, 4);
Posted: Fri May 09, 2008 1:22 pm
by jp
Thanks Sergey,
One remark. If the jpeg have been resized in ActionTest2007 the width and height is set between the TJPEGImage and the FF D8(the hex for the begin of the jpeg)
I have made it so that I look up the FF D8 in the stream en then set the position back -4. Then I read the size with Source.ReadBuffer(Size, 4);
My next question is kan i do the same thing for other formates - TBitmap, TMetafile, TIcon, etc.? And is there a solution for png's?
JP
Posted: Fri May 09, 2008 2:44 pm
by Sergey Tkachenko
Well, yes, this data sequence (image class name, line break, data size, image data) is used only if there are no additional properties for this item.
If you resize the image in the editor, 2 additional properties (ImageWidth and ImageHeight) appear. They are saved before the data size. Each additional property is stored on one line. You cannot know how many additional properties are stored unless you read the header line for this item.
Image item is stored as:
<header><line break>
<item name><line break>
<image class><line break>
<additional properties, 1 property per line>
<data size><image data>
So I can suggest the following procedure:
1) Search for 'TJPEGImage'
2) Skip the line before it (lines are separated by #13#10)
3) Read the line before. This is a header line, it consists of several integer values separated with spaces. The first value must be -3 (identifies a picture item). The second value is a number of lines between the header and image data size minus 1 (i.e., if this value is 3, there are 2 lines between the header and the image data size)
4) Skip this number of lines from the header.
5) Read image data size and image data.
For other types of pictures, the procedure is exactly the same, only class name is different,
Posted: Wed May 14, 2008 9:04 am
by jp
Thanks Sergey
This great - I can now wrtie a function witch can handle all types Images.
Only two more questions:
Are I right in assuming that the header, Item name, Image Class are items that RichView is setting in the stream?
And how can I best read backwards in the stream? I mean how do I come fram 'TJPEGImage' to the begin of the Header?
JP
Posted: Wed May 14, 2008 3:19 pm
by Sergey Tkachenko
I do not understand the first questions. All these lines (header, item text, image class, etc.) represents one item in RVF.
The link for detailed RVF specification is
http://www.trichview.com/help/index.htm ... ation.html
If you use TMemoryStream, you can access data as Stream.Memory. The current position can be read and set using Stream.Position (for all types of streams)