- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm new to UIC, and I'm trying to figure out how to use the BMP decoder. I think I'm following the example, but I'm getting heap corruption at the end of my file. I'm trying to decode a 24 BPP BGR bitmap saved out by a C# .NET program, but I get the same results on several BMP images. I'll put my short example code below, but I had several questions:
1) is it possible to allocate the image memory myself, or do I have to use the UIC buffers?
2) How does one copy a UIC image?
Any help appreciated.
1) is it possible to allocate the image memory myself, or do I have to use the UIC buffers?
2) How does one copy a UIC image?
Any help appreciated.
[cpp]#include "stdfilein.h" #include "stdfileout.h" #include "uic_bmp_dec.h" using namespace UIC; typedef unsigned int uint; inline uint AlignStep(uint step) { return (step + 31) & 0xFFFFFFE0; } char* color_str[] = { "Unknown", "Grayscale", "RGB", "BGR", "YCbCr", "CMYK", "YCCK", "YUV" }; int decodeBMP(BaseStreamInput& in, Image& image) { BMPDecoder decoder; ImageSamplingGeometry samplingGeometry; ImageDataPtr dataPtr; ImageDataOrder dataOrder; if(!IsOk(decoder.Init())) { return 1; } if(!IsOk(decoder.AttachStream(in))) { return 1; } if(!IsOk(decoder.ReadHeader(image.ColorSpec(), samplingGeometry))) { return 1; } uint nOfComponents = samplingGeometry.NOfComponents(); //dataOrder.SetDataType(T8u); if(!IsOk(dataOrder.ReAlloc(Interleaved, nOfComponents))) { return 1; } for(uint component = 0; component < nOfComponents; component++) { dataOrder.PixelStep()[component] = nOfComponents; dataOrder.LineStep() [component] = AlignStep(samplingGeometry.RefGridRect().Width() * dataOrder.PixelStep()[component]); } image.ColorSpec().ReAlloc(nOfComponents); image.ColorSpec().SetColorSpecMethod(Enumerated); image.ColorSpec().SetComponentToColorMap(Direct); for(uint i = 0; i < nOfComponents; i++) image.ColorSpec().DataRange().SetAsRange8u(255); image.ColorSpec().SetEnumColorSpace(UIC::BGR); if(!IsOk(image.Buffer().ReAlloc(dataOrder, samplingGeometry))) { return 1; } if(!IsOk(decoder.ReadData(image.Buffer().DataPtr(), image.Buffer().BufferFormat().DataOrder()))) { return 1; } int a = 1; return 0; } int main(int argc, char* argv[]) { ExcStatus res; CStdFileInput fi; CStdFileOutput fo; Image image; if(argc < 2) { printf("only got %d args\n", argc); return 1; } if(!BaseStream::IsOk(fi.Open(argv[1]))) return 1; res = decodeBMP(fi,image); if(!IsOk(res)) return 1; printf("file: %s\n",argv[1]); printf("%dx%dx%d, %d-bits, color: %s\n", image.Buffer().BufferFormat().SamplingGeometry().RefGridRect().Width(), image.Buffer().BufferFormat().SamplingGeometry().RefGridRect().Height(), image.Buffer().BufferFormat().SamplingGeometry().NOfComponents(), image.ColorSpec().DataRange()[0].BitDepth() + 1, color_str[image.ColorSpec().EnumColorSpace()]); }[/cpp]
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
you need
to remove heap corruption you need to make some modification of your sample code:
istead of
[cpp] for(uint component = 0; component < nOfComponents; component++) { dataOrder.PixelStep()[component] = nOfComponents; dataOrder.LineStep() [component] = AlignStep(samplingGeometry.RefGridRect().Width() * dataOrder.PixelStep()[component]); } [/cpp]
[cpp] dataOrder.PixelStep()[0] = nOfComponents; dataOrder.LineStep()[0] = samplingGeometry.RefGridRect().Width() * nOfComponents + BYTES_PAD(samplingGeometry.RefGridRect().Width(), nOfComponents, 1);[/cpp]
there is BYTES_PAD is
[cpp]#define ALIGN_VALUE (sizeof(int) - 1) #define BYTES_PAD(iWidth, iChannels, iDU) (((iWidth * iChannels * iDU + ALIGN_VALUE) & (~ALIGN_VALUE)) - iWidth * iChannels * iDU)[/cpp]
About questions:
1) where is no problem in using external users buffers to store decoded image in it. The sample code below show how it can be done:
[cpp] Ipp32u size; Ipp8u* buff; ImageDataPtr dataPtr; size = dataOrder.LineStep[0] * samplingGeometry.RefGridRect().Width(); buff = (Ipp8u*)ippMalloc(size); dataPtr.p8u = buff; image.Buffer().Attach(&dataPtr, dataOrder, samplingGeometry); [/cpp]in theis case you don need to realloc Image.Buffer() like you did in:
[cpp]if(!IsOk(image.Buffer().ReAlloc(dataOrder, samplingGeometry)))[/cpp]
2) sorry, but it is not clear for me what you mean in this question. is it "how can i copy decoded image from UIC::Image object"?
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
you need
to remove heap corruption you need to make some modification of your sample code:
istead of
[cpp] for(uint component = 0; component < nOfComponents; component++) { dataOrder.PixelStep()[component] = nOfComponents; dataOrder.LineStep() [component] = AlignStep(samplingGeometry.RefGridRect().Width() * dataOrder.PixelStep()[component]); } [/cpp]
[cpp] dataOrder.PixelStep()[0] = nOfComponents; dataOrder.LineStep()[0] = samplingGeometry.RefGridRect().Width() * nOfComponents + BYTES_PAD(samplingGeometry.RefGridRect().Width(), nOfComponents, 1);[/cpp]
there is BYTES_PAD is
[cpp]#define ALIGN_VALUE (sizeof(int) - 1) #define BYTES_PAD(iWidth, iChannels, iDU) (((iWidth * iChannels * iDU + ALIGN_VALUE) & (~ALIGN_VALUE)) - iWidth * iChannels * iDU)[/cpp]
About questions:
1) where is no problem in using external users buffers to store decoded image in it. The sample code below show how it can be done:
[cpp] Ipp32u size; Ipp8u* buff; ImageDataPtr dataPtr; size = dataOrder.LineStep[0] * samplingGeometry.RefGridRect().Width(); buff = (Ipp8u*)ippMalloc(size); dataPtr.p8u = buff; image.Buffer().Attach(&dataPtr, dataOrder, samplingGeometry); [/cpp]in theis case you don need to realloc Image.Buffer() like you did in:
[cpp]if(!IsOk(image.Buffer().ReAlloc(dataOrder, samplingGeometry)))[/cpp]
2) sorry, but it is not clear for me what you mean in this question. is it "how can i copy decoded image from UIC::Image object"?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks!
My misunderstanding was that the pixelStep and LineStep were for each channel and not for the entire image. I had stolen that code from the JPEG2000 example which had plane data and not like BMP which uses interleaved, which was my error.
Thanks also for the example of ippMalloc. It makes sense to use such a function because like ReAlloc the deallocation matches the allocation. For optimization, it would be nice to pass in an external (non-IPP) buffer when decoding. But, it would have to use malloc, which my external library doesn't use. So, I'll just memcpy it when done...
As for copying images, I have figured out what I want.
I really appreciate your fast, accurate response.
My misunderstanding was that the pixelStep and LineStep were for each channel and not for the entire image. I had stolen that code from the JPEG2000 example which had plane data and not like BMP which uses interleaved, which was my error.
Thanks also for the example of ippMalloc. It makes sense to use such a function because like ReAlloc the deallocation matches the allocation. For optimization, it would be nice to pass in an external (non-IPP) buffer when decoding. But, it would have to use malloc, which my external library doesn't use. So, I'll just memcpy it when done...
As for copying images, I have figured out what I want.
I really appreciate your fast, accurate response.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would like to suggest you to use Photoshop to create test images in all possible BMP formats, and then try to decode those using UIC so you know in advance what works and what doesn't.
I was a bit disappointed and I wrote my own decoder in the end.
I was a bit disappointed and I wrote my own decoder in the end.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your suggestion, Igor.
By the way, in IPP 7.0 we have fixed issues which you reported out on previous version of UIC BMP decoder.
Note, there are still some limitations on UIC BMP implementation (like old OS/2 BMP format, 1, 4 or 16 bits per pixel formats and some others). Our goal in UIC BMP implementation is to provide simple code which handle most of true color BMP files. UIC development focus is on more complex image compression formats.
Regards,
Vladimir
By the way, in IPP 7.0 we have fixed issues which you reported out on previous version of UIC BMP decoder.
Note, there are still some limitations on UIC BMP implementation (like old OS/2 BMP format, 1, 4 or 16 bits per pixel formats and some others). Our goal in UIC BMP implementation is to provide simple code which handle most of true color BMP files. UIC development focus is on more complex image compression formats.
Regards,
Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Vladimir,
I suggested them to check because some developers might have different requirements (if you are writing image viewer or converter you will want to support even those old formats).
I am not saying that UIC::BMP class is useless, just that it has limitations which should be carefully considered.
I suggested them to check because some developers might have different requirements (if you are writing image viewer or converter you will want to support even those old formats).
I am not saying that UIC::BMP class is useless, just that it has limitations which should be carefully considered.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page