Unexpected result when drawing bmp from buffer - c

The last time i had problem with this was because i swapped WIDTH and HEIGHT in the wrong way. After that i have been told for correct way and i fixed it. However.. today i noticed that the function isn't working as it was expected on some bmp images.
I am rendering the image from a buffer that has all the image's byte data.
And there is the function to render:
void bmp_bdraw (BYTE* BUFF)
{
word WIDTH, HEIGHT, W, H; // word - unsigned short
BYTE R, G, B; // BYTE - unsigned char
(!BUFF || !BUFF[COUNT-1]) ? // debug1
(error("Error in function 'bmp_bdraw'. There is no data to read from.")) : ;
WIDTH = BUFF[18] + BUFF[19] * 256;
HEIGHT = BUFF[22] + BUFF[23] * 256;
ofs = 54;
if(BUFF[0] != 'B' | BUFF[1] != 'M') error // debug2
("Warning: Data identifier error in function 'bmp_bdraw' occurred. Invalid BMP file loaded.");
for(H=HEIGHT-1; H>=0; H--)
{
for(W=0; W<WIDTH; W++)
{
B = sgetc(BUFF); // fgetc-like function but from buff
G = sgetc(BUFF);
R = sgetc(BUFF);
setpen(R, G, B, 0, 1); // sets the color, transparancy and size of the pen
putpixel(W, H); // and puts the pixel at the right location
}
}
if(W != WIDTH || H > 1) // debug3
error("Error in function 'bmp_bdraw'. Rendering failed. The file might be damaged.");
if(real_fps < 11)
error("Too low fps rate."); // debug4
}

If your input data here (BUFF buffer) is correct then
I am sharing my observation with you so you can debug further more.
You are rendering from (H(max),w(0)) to (H(0),w(max)). So in beging everything is good. Image is good but when your H(max) get decrease output image gets bad.
In simple term in bottom part of image output is good when in top part output is bad. It seems like pixel get strinked in top part.
I do not understand how setpen() works. and after processing you should paint that pixel at same position or not?
I think As H(max) decrease with that you should decrease your W value in putpixel(W, H); I think this will remove that inclined vertical line and bad image issue.

Related

Animated ASCII art flickering in c

I'm making an ASCII art game in c (windows), but for some reason when i play it is all flickering at apparently random intervals, and for most of the time i can't see anything. can anyone explain why or how to solve it?
this is my code:
const int WIDTH = 20, HEIGTH = 5;
const int AREA = (WIDTH) * HEIGTH;
const int gl = HEIGTH - 2; //Ground level
const float delta = 0.1f; //Frame rate
char scr[AREA]; //String for displaying stuff
char input;
int posx = 10, posy = gl - 1; //Player position
int vel = 0; //player velocity
while(1)
{
//TODO: player input
for(i = 0; i < AREA; i++) //Rendering part
{
if(i % WIDTH == 0 && i != 0)
{
scr[i] = '\n';
continue;
}
if(floor(i / WIDTH) >= gl) //i is on ground
{
scr[i] = '.';
continue;
}
scr[i] = ' ';
}
//Set player position
scr[posy * WIDTH + posx + 1] = '#';
scr[(posy + 1) * WIDTH + posx + 1] = '#';
system("cls");// Clear terminal
printf(scr);// Print screen
usleep(delta * 1000);//Sleep
}
output:
#
..........#........
...................►↓#
It works, but it flickers...
One possible reason for your problem is that there may be output waiting in the output buffer when you call your sleep function usleep. In that case, you should always flush all output before sleeping, by calling the function fflush( stdout );.
Also, using system("cls"); is highly inefficient. It is generally better to use the Console Functions API, or, if you are targetting platforms with Windows 10 or later, you can also use Console Virtual Terminal Sequences instead.
If you decide to use the Console Functions API, then the main functions that you will be needing in order to replace system("cls"); are GetStdHandle to obtain the output handle, and SetConsoleCursorPosition. That way, you won't have to clear the whole screen, but will only have to overwrite the parts of the screen that are changing. I also recommend that you replace printf with WriteConsole, otherwise you may run into buffering issues.
If this does not solve your flickering problem, then there also is the possibility of using double-buffering. Both the Console Functions API and Console Virtual Terminal Sequences support this.
When using the Console Functions API, you can use the function CreateConsoleScreenBuffer to create a new buffer to write to, without it being displayed immediately. This will allow you to first finish building the next screen, without any flickering occuring while doing so (because it is not being displayed yet). Once you have finished building the next screen, you can display it using the function SetConsoleActiveScreenBuffer.
Console Virtual Terminal Sequences offer similar functionality by supporting an alternate screen buffer.

C - Pthread goes into infinite loop unless I draw the image in between a given set of threads

void put_mandelbrot(int x_left, int x_right, int y_top, int y_bot)
{
pthread_t workers[10];
t_param inputs[10];
int i;
int x;
int y;
i = -1;
y = y_top - 1;
while (++y < y_bot)
{
x = x_left - 1;
while (x < x_right)
{
if (++i < 10)
{
inputs[i] = (t_param){++x, y};
pthread_create(&workers[i], 0, (void *(*)(void *))mandelbrot_thread, (void *)&inputs[i]);
}
else
while (--i > -1)
pthread_join(workers[i], 0);
}
while (--i > -1)
pthread_join(workers[i], 0);
// calling draw_image() here will get the correct result, drawn line by line
}
// if I don't call draw_image() above and for example want to draw
// the whole image here after all of the lines are iterated
// the program will become unresponsive
}
If I have the "draw_image()" function call in between each line, I get the image line by line and the program finishes it (I have checked this). On the other hand, if I only call the "draw image()" function after all of the iterations for all points (x, y) have been completed, the program never draws a single pixel and is unresponsive.
The "mandelbrot_thread" function simply iterates over a pixel (x, y) and sets the color of the pixel to a global image buffer which is always drawn in its entirety with the "draw_image()" call.
Why is this? I can't draw the image after every line as that makes the program insanely slow and makes no sense anyway. At the moment it seems to me that pthreads is working only when I'm actively checking it, almost as if to hide from any debugging attempts.
(edit: my mac also makes a very disturbing sound when I run this program, so there must be something very wrong with this)

libjpeg turbo tjCompressFromYUV

I'd like to compress a planar 4:2:0 YUV buffer to a jpeg image using libturbojpeg in C, but I'm having trouble using the tjCompressFromYUV() function.
This is my code:
#define PADDING 2
tjhandle tjh;
unsigned long buf_size;
unsigned char *jpegBuf = NULL;
unsigned long jpegSize;
int width = 352;
int height = 288;
int quality = 70;
unsigned char *ucp_frame;
int j;
FILE *fp = NULL;
ucp_frame = malloc(width * height * 3 / 2);
if ( NULL == ucp_frame ) {
printf("malloc error ucp_frame\n");
return 0;
}
fp = fopen("planar_352x288.raw", "rb");
if( NULL == fp ) {
printf("fopen error\n");
return 0;
}
j = fread( ucp_frame, 1, width * height * 3 / 2, fp);
if( j != width * height * 3 / 2 ) {
printf("fread error\n");
return 0;
}
fclose(fp);
tjh = tjInitCompress();
if( NULL == tjh ) {
printf("tjInitCompress error '%s'\n", tjGetErrorStr() );
return 0;
}
buf_size = tjBufSizeYUV2( width, PADDING, height, TJSAMP_420);
jpegBuf = tjAlloc(buf_size);
if( tjCompressFromYUV( tjh, ucp_frame, width, PADDING, height,
TJSAMP_420, &jpegBuf, &jpegSize, quality,
TJFLAG_NOREALLOC ) ) {
printf("tjCompressFromYUV error '%s'\n", tjGetErrorStr() );
}
The error string returned by tjGetErrorStr() is "Bogus input colorspace".
I tried linking libturbojpeg versions 1.4.2 and 1.4.90.
Any help wolud be appreciated,
Thanks
Turbojpeg API tjCompressFromYUV allows you such options for jpegBuf:
#param jpegBuf address of a pointer to an image buffer that will receive the
JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to
accommodate the size of the JPEG image. Thus, you can choose to:
pre-allocate the JPEG buffer with an arbitrary size using #tjAlloc() and
let TurboJPEG grow the buffer as needed,
set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer
for you, or
pre-allocate the buffer to a "worst case" size determined by calling
tjBufSize(). This should ensure that the buffer never has to be
re-allocated (setting #TJFLAG_NOREALLOC guarantees this.)
If you choose option 1, *jpegSize should be set to the size of your
pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC,
you should always check *jpegBuf upon return from this function, as
it may have changed.
So by using 2-nd option, there is no need to call tjBufSizeYUV2 and tjAlloc, simply have jpegBuf=NULL before calling tjCompressFromYUV and do tjFree after compressing.
Ok it turned out the problem was in the program containing the code I posted, in a smaller test program the tjBufSizeYUV2 call performs as expected.
On a side note it seems that if jpegBuf is pre-allocated before calling tjBufSizeYUV2, the flag argument passed to tjBufSizeYUV2 must contain TJFLAG_NOREALLOC, or else jpegBuf won't be freed even if tjFree(jpegBuf); is later called.
#define PADDING 4
jpegBuf = tjAlloc(width*height*3/2);

Comparing images in which some parts are variable, but should not matter

I am concerned about to find dissimilarities between images as shown in the samples underneath with the black oval shape.
My problem is that some part of image is also variable, but I do not want to consider this part when finding dissimilarities. To overcome this problem I want to make "transparent" that area which is now marked with red color: the variable part Date/Time and the Date/Time edit field should be excluded from comparison as can be seen from image below:
One way is:
I can use a “transparent” color to mark image areas that should not be compared. To do this, I need to modify the baseline copy of an image in the following manner:
Open the baseline image in an image editor (for instance, in MSPaint).
Select the color that you will use as the “transparent” color.
Change the color of the top-left pixel to the “transparent” color.
Use the “transparent” color to fill image areas that you want to exclude from comparison.
How to do automate above manual work through coding? I want to implement above behavior in C code.
My suggestion is:
First implement the solution as a command line with ImageMagick.
Once this works, port this command line over to ImageMagick's C API.
Here are a few answers about comparing images using ImageMagick compare. They may not apply to your precise question, but thy provide enough theoretical background with practical examples to get you started:
ImageMagick compare executable: unrecognized option -metric
Can we programatically compare different images of same resolutions?
ImageMagick: “Diff” an Image
ImageMagick compare: Disregard white matches from the PSNR result
If I understand your question correctly, you do want to compare only some parts of two images, any you want to exclude other parts from the comparison where you already know there are (uninteresting) differences. Right?
Taking these two images as an example:
BTW, these two images have been born as PDFs, and I could apply the procedure described below to PDF pages too (without a need to convert them to image files first).
You do not necessarily need a transparent mask -- you can use a black (or any color) one too.
Create a green mask of 280x20 pixels size:
convert -size 280x20 xc:green greenmask-280x20.png
Now use composite to place the mask on top of each of the images:
convert \
http://i.stack.imgur.com/Q1pyC.png \
greenmask-280x20.png \
-geometry +32+35 \
-compose over \
-composite \
c.png
convert \
http://i.stack.imgur.com/JVije.png \
greenmask-280x20.png \
-geometry +32+35 \
-compose over \
-composite \
r.png
The -geometry +32+35 parameter maybe requires some explanation: it tells ImageMagick to place the top left corner of the greenmask 32 pixels to the right and 35 pixels to the bottom of the top left corner of the original image.
The resulting images are here:
An answer that discusses the different compose methods known to ImageMagick is here:
Superpose two sets of images
Now your images are ready for either statistical or visual comparison, provided by ImageMagick's compare command:
compare c.png r.png -compose src delta.png
The delta.png shows all pixels in red which are different, the rest is white:
Or, using the most simple compare command, where the reference image serves as a pale background with red delta pixels on top:
compare c.png r.png delta2.png
If you are providing a rectangle to colour in, why not just ignore a rectangular area in the first place? Here is some pseudo code
int compareimages (char *im1, char* im2, int wid, int dep, int x0, int y0, int x1, int y1) {
int x, y;
for (y=0; y<dep; y++)
for (x=0; x<wid; x++)
if (x<x0 || x>x1 || y<y0 || y>y1) // if outside rectangle
if im1[y*wid+x] != im2[y*wid+x] // compare pixels
return 0;
return 1;
}
UPDATE for several areas to be ignored, which may overlap.
Still not hard: just provide an array of rectangles. It is still going to be easier than going to the trouble of painting out areas when you can check them in the first place.
#include <stdio.h>
#define WID 200
#define DEP 600
typedef struct {
int left;
int top;
int right;
int bot;
} rect;
char image1[WID*DEP];
char image2[WID*DEP];
int inrect (int x, int y, rect r) {
if (x<r.left || x>r.right || y<r.top || y>r.bot)
return 0;
return 1;
}
int compareimages (char *im1, char* im2, int wid, int dep, rect *rarr, int rects) {
int x, y, n, ignore;
for (y=0; y<dep; y++)
for (x=0; x<wid; x++) {
ignore = 0;
for (n=0; n<rects; n++)
ignore |= inrect (x, y, rarr[n]);
if (!ignore)
if (im1[y*wid+x] != im2[y*wid+x]) // compare pixels
return 0;
}
return 1;
}
int main(void) {
rect rectarr[2] = { {10, 10, 50, 50}, { 40, 40, 90, 90 }};
// ... load images ...
// put pixel in one of the rectangles
image1[20*WID+20] = 1;
if (compareimages (image1, image2, WID, DEP, rectarr, 2))
printf ("Same\n");
else
printf ("Different\n");
// put pixel outside any rectangles
image1[0] = 1;
if (compareimages (image1, image2, WID, DEP, rectarr, 2))
printf ("Same\n");
else
printf ("Different\n");
return 0;
}
Program output:
Same
Different
EDIT added another version of the function, comparing 4 pixel components.
int compareimages (char *im1, char* im2, int wid, int dep, rect *rarr, int rects) {
int x, y, n, ignore;
for (y=0; y<dep; y++)
for (x=0; x<wid; x++) {
ignore = 0;
for (n=0; n<rects; n++)
ignore |= inrect (x, y, rarr[n]);
if (!ignore) {
if (im1[y*wid*4+x] != im2[y*wid*4+x]) // compare pixels
return 0;
if (im1[y*wid*4+x+1] != im2[y*wid*4+x+1])
return 0;
if (im1[y*wid*4+x+2] != im2[y*wid*4+x+2])
return 0;
if (im1[y*wid*4+x+3] != im2[y*wid*4+x+3])
return 0;
}
}
return 1;
}
Normally, such an 'image' as is used in the example is NOT a single image.
Rather it is a large number of images overlaying each other.
Most likely, the 'image' is made of:
the background
the outside border (which has 4 parts)
the upper left icon
the upper border clickable button( three of them)
the text field: Date/Time:
the input field: (for the date/time)
the text field: 'Table:'
the input multi line field/ with initial text 'Customers'
etc etc etc
I.E. that is not a single image but rather many images
that overlay each other
a single image would be something like a .bmp or .tif or .jpg file

Display RGBA32-BMP Images on Linux

today I got some code to review.
Since the code is going to work on an headless pc the code saves every frame as a seperate RGBa image.
On my Ubuntu install I cannot view theses images, GIMP complains about a broken header. Imagemagick options convert or display also did not show any images.
Here's the code fragment that generates the image:
if (act.doScreenshot || (act.doVideo && buddhabrot_animate.animating))
{
uchar4* tmpBuffer = new uchar4[env.static_env.save.imageW
* env.static_env.save.imageH];
for (int i = 0; i < env.static_env.save.imageW * env.static_env.save.imageH; i++)
{
const unsigned char tmp = tmpBuffer[i].x;
tmpBuffer[i].x = tmpBuffer[i].z;
tmpBuffer[i].z = tmp;
}
char filename[128];
FILE* fp = fopen(filename, "w+b");
BITMAPFILEHEADER bmpFH;
BITMAPINFOHEADER bmpIH;
memset(&bmpFH, 0, sizeof(bmpFH));
memset(&bmpIH, 0, sizeof(bmpIH));
bmpFH.bfType = 19778; //"BM"
bmpFH.bfSize = sizeof(bmpFH) + sizeof(bmpIH) + env.static_env.save.imageW * env.static_env.save.imageH;
bmpFH.bfOffBits = sizeof(bmpFH) + sizeof(bmpIH);
bmpIH.biSize = sizeof(bmpIH);
bmpIH.biWidth = env.static_env.save.imageW;
bmpIH.biHeight = env.static_env.save.imageH;
bmpIH.biPlanes = 1;
bmpIH.biBitCount = 32;
fwrite(&bmpFH, 1, sizeof(bmpFH), fp);
fwrite(&bmpIH, 1, sizeof(bmpIH), fp);
fwrite
(tmpBuffer,
env.static_env.save.imageW * env.static_env.save.imageH,
sizeof(uchar4),
fp);
fclose(fp);
delete[] tmpBuffer;
Is there any way to look at the image?
Or maybe another way to save the images as JPGs?
You don't calculate bmpFH.bfSize correctly, you need to multiply the number of pixels in the image by the size of the pixels (4). For example:
bmpFH.bfSize = sizeof(bmpFH) + sizeof(bmpIH) + env.static_env.save.imageW * env.static_env.save.imageH * sizeof(uchar4);
You should also initialize bmpIH.biCompression to BI_RGB. It'll work anyway because its value happens to be zero, but it's good to be explicit. You also might want to negate the value you're assigning to bmpIH.biHeight as positive height values indicate a bottom up image.

Resources