I'm dealing with machine embedded C language software and struggling to understand how to use 'putimage' function to load 'qrcode'image in c. What I've tried to do is put some image on the LCD panel screen on the machine and coudn't figure out how to use putimage function properly.
I've learned that 'putimage' function shows image data array which have gotten from 'getimage' function and two functions I've mentioned are used as below.
void putimage(int left, int top, void *bitmap, int op);
void getimage(int left, int top, int right, int bottom, void *bitmap) ;
Since it is said that bitmap files can be converted to hex format starting '0x42, 0x4D...', I've tried to put array which I've defined like 'char QRbuff[] = {'0x42, 0x4D,...,}' into '*bitmap' parameter while using 'putimage'fuction. but no image have been appeared.
If I defined BMPbuff[] as below ingnoring bitmap format(eg. 0x42, 0x4D), some dotted image is shown.
char BMPbuff[] = {30, 0, 30, 0, 0x18, 0x24, 0x42, 0x99, 0x99, 0x42, 0x24, 0x18} ;
I have no idea how it works. I guess bitmap format that has to do with putimage is not the format which starts with 0x42, 0x4D. Instead, it seems that the format start with size of image {30, 0, 30, 0...} which I don't know where it came from.
I would be so appreciated with any help how to define bitmap array in this case...
Related
I am asking the question for the second time because the first time I apparently did not manage to get my request across (insert a sad smiley here).The previous post has been deleted as I thought it could just add to the confusion if I just edit it.
Problem: I am getting a packet of data (payload) from a data source. This data is given to me in an array and I would like to split this data (like in a gateway) and send it to other peripherals.
The package data I received could look like this:
uint8_t received_payload[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
It is noticeable that what is behind this data is not apparent. This is because it can be measurement data, which can sometimes come from several sensors and these measurement values were thrown together in a data package.
I can assume that the measured values come periodically and that I can recognize data packets based on an ID. (This does not matter here, however).
What is interesting for me now is that I want to pass on these measured values. Under certain circumstances split into two or more separate messages.
The order and position should be given somehow and somewhere.
In the following I have shown an example of how these can be listed. I would like to emphasize again that this is only an EXAMPLE and that I have freely come up with these values. I just want to show visually how the data could be swapped under certain circumstances.
uint8_t totransmit_payload_1[] = {0x11, 0x22, 0x33};
uint8_t totransmit_payload_2[] = {0x44, 0x66, 0x55};
So I would like to have something stored somewhere that corresponds to the following information content:
totransmit_payload_1[0] = received_payload[0];
totransmit_payload_1[1] = received_payload[1];
totransmit_payload_1[2] = received_payload[2];
totransmit_payload_2[0] = received_payload[3];
totransmit_payload_2[1] = received_payload[5];
totransmit_payload_2[2] = received_payload[4];
This process should work bidirectionally and have a kind of dynamic because it won't be possible for me to write "how the data is split up" in the code.(Before questions arise. When I boot my system via SPI, I get a configuration file from a MicroSD card which describes how my system should behave.)
Of course I have already tried to find solutions on the World Wide Web, but I find it difficult to find something for my low level application. I am on a microcontroller of the STM class and only program in C.
What I found that would fit my application would be a kind of mapping.
Here as references: What Is Data Mapping?
Do you guys or girls have experience with something like that? Or ideas on how something like this could work efficiently?
Thanks for your help :D
Edit: I just want to know the best way to save in C which position in an array references to another position in another array.
Without hardcoding it.
Seems like you you start asking about data copying, then change midway to data mapping? Anyway, these are small examples of both:
#include <string.h> // for memcpy
...
void CopyBytes(const* uint8_t received_payload, uint8_t* totransmit_payload_1, uint8_t* totransmit_payload_2)
{
// of course you'll need to make sure these buffers are appropriately sized
memcpy(totransmit_payload_1, received_payload, 3);
memcpy(totransmit_payload_2, received_payload + 3, 3);
}
Learn more about memcpy on the man page.
If you want some data mapping instead, I would create space for the actual data in one place (the receive buffer for instance), then you can have as many pointers as you want pointing to that data:
uint8_t received_payload[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
uint8_t* totransmit_payload_1[3]; // creates an array of uint8_t _pointers_
uint8_t* totransmit_payload_2[3]; // does the same
// now you can do your mapping
totransmit_payload_1[0] = &(received_payload[0]); // save the _address_ of received_payload[0] to totransmit_payload_1[0]
totransmit_payload_1[1] = &(received_payload[1]); // (don't think the parentheses are necessary, but I like them to be perfectly clear the [] dereference happens first)
totransmit_payload_1[2] = &(received_payload[2]);
totransmit_payload_2[0] = &(received_payload[3]);
totransmit_payload_2[1] = &(received_payload[5]);
totransmit_payload_2[2] = &(received_payload[4]);
Now, any time data changes in received_payload, you can access it from the totransmit_payload structures since they point to that data. For example:
received_payload[0] = 5;
printf("received_payload[0] = %" PRIu8 "\n", *(totransmit_payload_1[0])); // prints 5;
// It's "bi-directional", you can dereference the pointer and assign a value to that memory location, then access it from received_payload
*(totransmit_payload_2[2]) = 17;
printf("received_payload[4] = %" PRIu8 "\n", received_payload[4]); // prints 17
I have a raw image in memory, organized as an array of 32-bit RGB values. I'd like to write that out as quickly as possible to an image file so that I can free up the memory. Is there a way to do the following to write either an uncompressed JPEG, PNG or TIFF image? Or perhaps I should say, what image formats are compatible with this approach to writing raw pixel data? Note that the top-left pixel is in the first 4 bytes of the pixel data.
void write_image(uint32_t *pixels, int width, int height) {
FILE *file=fopen("file.jpg","wb");
write_header (file, width, height);
fwrite (pixels,1,width*height*4,file); // write raw pixel data
write_end (file);
fclose(file);
}
There seem to be two different issues or motivations on your part.
First, there is the desire to write an image in some uncompressed format to (presumably) gain speed. PNG and JPEG are compressed formats, though you can instruct the encoder (at least in some PNG implementations) to use the "no compress" setting.
However: a) there are few scenarios in which that "optimization" would make a critical difference, the normal compressors are quite quick.
b) Even when encoding using some compression_level=0 setting, you are still encoding the image in a particular format (typically a header, to start with). What leads us to the second motivation.
Second, it seems that you want to avoid not exactly (only) the compression, but the encoding. That is, you want to write the pixels in your unencoded ("raw") format. IN that case, of course, you cannot write a PNG or JPEG image. You can use your own or some standard RAW format, or the quasi-raw BMP format. But you still need to take care of how the pixels are organized in memory (for example, one byte per channel? RGB? BGR? RGBA ?) and perhaps some other issues (for example, BMP requires that the bytes per line are multiple of 4).
Uncompressed JPEG and PNG are non-trivial, and the results would likely have portability issues. Your simplest option might be TGA:
TGA was designed to store rasterized images that could be quickly loaded for display into frame buffers. It has a very simple 18-byte header, then raw pixel data. It's streamable, meaning image data can be written as generated, provided it's rasterized. There is no requirement for length/offset/CRC tables. The biggest limitation is samples must be in rasterized BGR order with an optional fourth channel (usually alpha but can be anything). The width/height fields in the header must be 16-bit little-endian. TGA format isn't as widely supported as GIF/JPEG/PNG, but you should find some viewers capable of rendering it.
For BGR data, the header would probably be (hexadecimal values):
0x00 0x00 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(width%256) (width/256) (height%256) (height/256) 0x18 0x20
For BGRA data, the header would probably be:
0x00 0x00 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(width%256) (width/256) (height%256) (height/256) 0x20 0x28
If your data is not in BGR/BGRA order and you can't or don't want to convert it, my second recommendation would be TIFF:
TIFF design is focused on storing rasterized scans of documents and uses a more complex TTLV-style header. It is not as streamable and requires offset tables, but you can get around this with brute-force precalculation and by defining the entire image as a single strip. Once you get the header done, then you can stream the raw pixel data in rasterized RGB or RGBA order as it's generated. TIFF can also support either big-endian or little-endian and up to 16-bits per sample. It is often the output format of choice for scanners, so viewer/editor support is fairly common.
The first four bytes are a magic number (byte order and TIFF file version), followed by a 4-byte offset of the image file directory (IFD). Usually this offset is just 8 bytes into the file to place the IFD immediately next. The IFD is a count value (N) followed by a table of N 12-byte entries in the form of tag, type, count, and value/offset. The rest of the details are too much to describe here but you can read the specification for more info.
TGA format is a good option for this. It is just a simple header followed by your data. 24 or 32 bits.
https://en.wikipedia.org/wiki/Truevision_TGA
I'd recommend svpng for debugging purposes.
https://github.com/miloyip/svpng
A minimalistic C function for saving RGB/RGBA image into uncompressed PNG.
Features
RGB or RGBA color format
Single function
32 lines of ANSI C code
No dependency
Customizable output stream (default with C file descriptor)
Example
void test_rgba(void) {
unsigned char rgba[256 * 256 * 4], *p = rgba;
unsigned x, y;
FILE* fp = fopen("rgba.png", "wb");
for (y = 0; y < 256; y++)
for (x = 0; x < 256; x++) {
*p++ = (unsigned char)x; /* R */
*p++ = (unsigned char)y; /* G */
*p++ = 128; /* B */
*p++ = (unsigned char)((x + y) / 2); /* A */
}
svpng(fp, 256, 256, rgba, 1);
fclose(fp);
}
I would like to do something simple like draw a square on the screen using C and SDL. The example that I copied is not working.
//Get window surface
SDL_Surface *screenSurface = SDL_GetWindowSurface(window);
//Fill the surface white
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF));
//create a square
SDL_FillRect(screenSurface, SDL_Rect(0,0,100,100), SDL_MapRGB(screenSurface->format, 0x00, 0x00, 0x00));
It correctly fills the screen white, but fails on the call to SDL_Rect:
error: expected expression before ‘SDL_Rect’
How do I correctly draw a square using SDL 2.0?
SDL_FillRect does not take an SDL_Rect as an argument; it takes a pointer to SDL_Rect.
//Create a square
SDL_Rect rect(0,0,100,100);
SDL_FillRect(screenSurface, &rect, SDL_MapRGB(...))
That is why when you fill with white you can pass NULL to the function. NULL is not of type SDL_Rect, but it is a pointer, so the compiler is fine with it.
As mentioned by Zach Stark, SDL_FillRect does not take an SDL_Rect as an argument. Rather, it takes a pointer to an SDL_Rect. By prefixing the variable with an ampersand (&), you pass only a reference (a pointer) to the original variable. However, I could not get Zach's code sample to work in my C program. The following uses a different syntax for creating an SDL_Rect but it worked for me.
// create a black square
SDL_Rect rect = {0, 0, 100, 100}; // x, y, width, height
SDL_FillRect(screenSurface, &rect, SDL_MapRGB(screenSurface->format, 0x00, 0x00, 0x00));
Check out SDL_RenderDrawRect.
I am trying to understand how I can draw a set of points (/set the pixels) that form a circle without using the library functions.
Now, getting the (x,y) co-ordinates of the points given the radius is straightforward.
for (x=-r; x <r; x=x+0.1) {
y = sqrt(r*r - x*x);
draw(x,y, 0, 0);
}
But once I have the points, how do you actually draw the circle is what is confusing to me. I can use the graphic library but I want to understand how you can do it without using the graphics library
void draw(float x, float y, float center_x, float center_y) {
//logic to set pixel given x, y and circle's center_x and center_y
// basically print x and y on the screen say print as a dot .
// u 'd need some sort of a 2d char array but how do you translate x and y
// to pixel positions
}
Could someone share any links/references or explain how this works?
char display[80][26];
void clearDisplay(void) {
memset(display, ' ', sizeof(display));
}
void printDisplay(void) {
for (short row=0; row<26; row++) {
for (short col=0; col<80; col++) {
printf("%c", display[col][row]);
}
printf("\n");
}
}
void draw(float x, float y, float center_x, float center_y) {
if (visible(x,y)) {
display[normalize(x)][normalize(y)] = '.';
}
}
EDITH:
you changed your comment, to incorporate more of your question, so I will expand my answer a bit.
you have two sets of coordinates:
world coordinates (like scaled longitude and latitude on a world map or femtometers on a electromagnet microscope) these are mostly your x and y
display coordinates: these are the representation of your displaying device, like a Nexus 7 or a Nexus 10 Tablet, with its physical dimensions (pixels or pels or dots per inch)
you need a metric, that transforms your world coordinates into display coordinates. To make things more complicated, you need a window (the part of the world you want to show the user) to clip the things you do cannot show (like africa, when you want to show europe). And you may want to zoom your world coordinates to match your display coordinates (how much of europe you want to display)
These metrics and clippings are simple algebraic transformations
zoom the world-coordinate to display-coordinate: display-x = world-x * factor (femtometer or kilometer to pixel)
translate the world-center to display-center: display-X + adjustment
and so on. Just wikipedia for "alegebraic transformation" or "geometrics"
It's a tough question because technically C doesn't have any built-in input/output capability. Even writing to a file requires a library. On certain systems, like real-mode DOS, you could directly access the video memory and set pixels by writing values into that memory, but modern OSes really get in the way of doing that. You could try writing a bootloader to launch the program in a more permissive CPU mode without an OS, but that's an enormous can of worms.
So, using the bare mimimum, the stdio library, you can write to stdout using ascii graphics as the other answer shows, or you can output a simple graphics format like xbm which can be viewed with a separate image-viewing program. A better choice might be the netpbm formats.
For the circle-drawing part, take a look at the classic Bresenham algorithm. Or, for way too much information, chapter 1 of Jim Blinn's A Trip Down the Graphics Pipeline describes 15 different circle-drawing algorithms!
I have a file that takes advantage of unicode braille.
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#define PIXEL_TRUE 1
#define PIXEL_FALSE 0
// Core Function.
void drawBraille(int type) {
if(type > 255) {
return;
}
setlocale(LC_CTYPE, "");
wchar_t c = 0x2800 + type;
wprintf(L"%lc", c);
}
/*
Pixel Array.
0x01, 0x08,
0x02, 0x10,
0x04, 0x20,
0x40, 0x80,
*/
int pixelArr[8] = {
0x01, 0x08,
0x02, 0x10,
0x04, 0x20,
0x40, 0x80
};
typedef int cell[8];
void drawCell(cell cell) {
int total;
for(int i = 0; i < 8; i++) {
if(cell[i] == 1) {
total += pixelArr[i];
}
}
drawBraille(total);
}
// Main.
int main(void) {
cell a = {
0, 1,
0, 0,
1, 1,
0, 1
};
drawCell(a);
return 0;
}
You're Welcome!
I am trying to run the sample code for tftp server. I get no complaints when synthesizing my hardware or compiling the code. However, when I add the lwip_init() statement, it seems to stop working (it doesn't output any of the print statements). This is very frustrating and I have no idea what is causing it. Any ideas? Thanks
#include <stdio.h>
#include "xenv_standalone.h"
#include "xparameters.h"
#include "platform.h"
#include "netif/xadapter.h"
#include "lwip/init.h"
#define EMAC_BASEADDR XPAR_LLTEMAC_0_BASEADDR
int main()
{
print("-- Starting main() -- \r\n");
struct netif *netif, server_netif;
struct ip_addr ipaddr, netmask, gw;
/* the mac address of the board. this should be unique per board */
unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
netif = &server_netif;
microblaze_init_icache_range(0, XPAR_MICROBLAZE_0_CACHE_BYTE_SIZE);
microblaze_init_dcache_range(0, XPAR_MICROBLAZE_0_DCACHE_BYTE_SIZE);
/* enable caches */
XCACHE_ENABLE_ICACHE();
XCACHE_ENABLE_DCACHE();
platform_setup_interrupts();
/* initliaze IP addresses to be used */
IP4_ADDR(&ipaddr, 192, 168, 1, 10);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gw, 192, 168, 1, 1);
print_app_header();
print_ip_settings(&ipaddr, &netmask, &gw);
lwip_init();
...
}
EDIT in response to vicky:
maybe you can explain something cause you might be right. When i compile it without lwip_init(), i get:
text data bss dec hex
7214 356 1104 8674 21e2
and with lwip_init() i get:
text data bss dec hex
9726 356 559080 569162 8af4a
which is ALOT bigger. too bad it can't give a warning about this
Presumably (assuming you are doing a clean rebuild) it's linking in lots of new stuff when you start calling LWIP functions, so your image has changed. Has your image overflowed any of its constraints (program size, data size, stack size...)?