Hey sorry for this novice question but I think im just missing something obvious... Would be very happy with the some guidance on this:
Inline docu of esp_camera.h:
/**
* #brief Data structure of camera frame buffer
*/
typedef struct {
uint8_t * buf; /*!< Pointer to the pixel data */
size_t len; /*!< Length of the buffer in bytes */
size_t width; /*!< Width of the buffer in pixels */
size_t height; /*!< Height of the buffer in pixels */
pixformat_t format; /*!< Format of the pixel data */
} camera_fb_t;
plus extract of demo code:
from esp32 code:
//replace this with your own function
display_image(fb->width, fb->height, fb->pixformat, fb->buf, fb->len);
code getting framebuffer
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
fb = esp_camera_fb_get(); // framebuffer in grayscale
and feed fb buffer into imagebuffer
int w, h;
int i, count;
uint8_t *imagebuffer = quirc_begin(qr, &w, &h);
//Feed 'fb' into 'imagebuffer' somehow?
//-------------------------------
// ----- DUMMY CODE?! not the proper way? ----
imagebuffer = fb->buf; //fb's own buf field, holding the pixel data
//Comment from quirc below:
/* Fill out the image buffer here.
* 'imagebuffer' is a pointer to a w*h bytes.
* One byte per pixel, w pixels per line, h lines in the buffer.
*/
//
quirc_end(qr);
Inline comment docu of quirc below:
/* These functions are used to process images for QR-code recognition.
* quirc_begin() must first be called to obtain access to a buffer into
* which the input image should be placed. Optionally, the current
* width and height may be returned.
*
* After filling the buffer, quirc_end() should be called to process
* the image for QR-code recognition. The locations and content of each
* code may be obtained using accessor functions described below.
*/
uint8_t *quirc_begin(struct quirc *q, int *w, int *h);
void quirc_end(struct quirc *q);
https://github.com/dlbeer/quirc
I've looked through the code, source files etc, but as i'm a novice ive no clue how to merge or feed the one into the other.
Could anyone point me into the right direction here? Am not dirty of looking through heaps of code but my inexperience with C is the issue here :S Thanks!
Author of the library was kind enough to explain it,
posting the code answer here as it may help others:
int w, h;
int i, count;
uint8_t *buff = quirc_begin(qr, &w, &h);
//
int total_pixels = w * h;
for (int i = 0; i < total_pixels; i++) {
// grab a pixel from your source image at element i
// convert it somehow, then store it
buff[i] = fb->buf[i]; //?
}
//
quirc_end(qr);
count = quirc_count(qr);
Serial.println("count found codes:");
Serial.println(count);
github issue with lib author's explaination
Related
Hello my task is to copy full structure into a new one, and allocate structure memory.
I want to copy one structure into another and also I want to copy the memory of it. So if I "free" the first structure, then I will have this information in the memory located.
struct bmp_image* flip_vertically(const struct bmp_image* image) {
struct bmp_image* bmp = NULL;
bmp = (struct bmp_image*)realloc(bmp, sizeof(struct bmp_image));
memcpy(bmp, image, sizeof(struct bmp_image));
return bmp;
}
What can be the problem?
For example:
If I know that the
image->data[5].blue is 255 and I want to copy it but I need also to save that information into the memory
Main task is to flip the bmp picture. Everything is working perfect for me, but if I put this source code for test that writes that:
Running suite(s): flip_horizontally()
stderr
double free or corruption (!prev)
that means the test is somewhere free-ing the old structure so I don't have this information in the new one
struct bmp_header{
uint16_t type; // "BM" (0x42, 0x4D)
uint32_t size; // file size
uint16_t reserved1; // not used (0)
uint16_t reserved2; // not used (0)
uint32_t offset; // offset to image data (54B)
uint32_t dib_size; // DIB header size (40B)
uint32_t width; // width in pixels
uint32_t height; // height in pixels
uint16_t planes; // 1
uint16_t bpp; // bits per pixel (1/4/8/24)
uint32_t compression; // compression type (0/1/2) 0
uint32_t image_size; // size of picture in bytes, 0
uint32_t x_ppm; // X Pixels per meter (0)
uint32_t y_ppm; // X Pixels per meter (0)
uint32_t num_colors; // number of colors (0)
uint32_t important_colors; // important colors (0)
} __attribute__((__packed__));
/**
* This structure describes a color consisting of relative intensities of
* red, green, and blue.
*/
struct pixel {
uint8_t blue;
uint8_t green;
uint8_t red;
//uint8_t alpha;
} __attribute__((__packed__));
/**
* Structure describes the BMP file format, which consists from two parts:
* 1. the header (metadata)
* 2. the data (pixels)
*/
struct bmp_image {
struct bmp_header* header;
struct pixel* data; // nr. of pixels is `width` * `height`
};
Main.c
int main () {
struct bmp_image* image = NULL;
FILE *stream = fopen("assets/saboteur.bmp", "r");
image = read_bmp(stream);
FILE *output_p1 = fopen("square2.bmp", "w");
struct bmp_image* newimage1 = NULL;
newimage1 = flip_vertically(image);
free_bmp_image(image);
write_bmp(output_p1, newimage1);
free(newimage1);
fclose(output_p1);
fclose(stream);
return 0;
}
If I free the image (the old structure) it shows for me a lot of errors, and I can't write it to the file. That means for me that it wants to read from the old structure.
memcpy does a "shallow" copy and not a "deep" copy. A shallow copy will copy only the pointer values in the struct bmp_image and not the memory it points to. To do a deep copy, the individual fields need to be allocated and copied. Here is some illustrative code. Error checking has been left out for brevity but for final code all allocation results should be checked.
struct bmp_image* flip_vertically(const struct bmp_image* image) {
bmp = malloc(sizeof(*bmp));
bmp->header = malloc(sizeof(*(bmp->header)));
*bmp->header = *(image->header);
size_t pixel_data_size =
sizeof(*(bmp->data)) * bmp->header->width * bmp->header->height;
bmp->data = malloc(pixel_data_size);
memcpy(bmp->data, image->data, pixel_data_size);
return bmp;
}
This is my first post here and I'm fairly new to programming and especially with C. A couple weeks ago I started working through the Audio Programming Book(MIT press) and have been expand on some examples to try to understand things further.
I think my question lies with how I'm trying to pass data (retrieved from the user in an initialization function) to a PortAudio callback. I feel like what I've done isn't that different from the examples (both from the book and PortAudio's examples like paex_sine.c), but for some reason I can't my code to work and I've been banging my head against a wall trying to understand why. I've tried searching pretty extensively for solutions or example code to study, but I kind of don't know what I don't know, so that hasn't returned much.
How do I get user data into the callback?
Am I just not understanding how pointers and structs work and trying to force them to do things they don't want to?
Or, am I just overlooking something really obvious?
The following code either gives a really high pitched output, short high pitched blips, or no (audible) output:
#include <stdio.h>
#include <math.h>
#include "portaudio.h"
#define FRAME_BLOCK_LEN 64
#define SAMPLING_RATE 44100
#define TWO_PI (3.14159265f * 2.0f)
PaStream *audioStream;
double si = 0;
typedef struct
{
float frequency;
float phase;
}
paTestData;
int audio_callback (const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeinfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
// data->frequency = 400;
for(i = 0; i < framesPerBuffer; i++){
si = TWO_PI * data->frequency / SAMPLING_RATE; // calculate sampling-incr
*out++ = sin(data->phase);
*out++ = sin(data->phase);
data->phase += si; // add sampling-incr to phase
}
return paContinue;
}
void init_stuff()
{
float frequency;
int i;
PaStreamParameters outputParameters;
paTestData data;
printf("type the modulator frequency in Hz: ");
scanf("%f", &data.frequency); // get modulator frequency
printf("you chose data.frequency %.2f\n",data.frequency);
data.phase = 0.0;
printf("initializing Portaudio. Please wait...\n");
Pa_Initialize(); // initialize Portaudio
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
Pa_OpenStream( // open paStream object
&audioStream, // portaudio stream object
NULL, // input params
&outputParameters, // output params
SAMPLING_RATE, // SampleRate
FRAME_BLOCK_LEN, // frames per buffer
paNoFlag, // set no Flag
audio_callback, // callbak function address
&data ); // user data
Pa_StartStream(audioStream); // start the callback mechanism
printf("running... press space bar and enter to exit\n");
}
void terminate_stuff()
{
Pa_StopStream(audioStream); // stop callback mechanism
Pa_CloseStream(audioStream); // destroy audio stream object
Pa_Terminate(); // terminate portaudio
}
int main(void)
{
init_stuff();
while(getchar() != ' ') Pa_Sleep(100);
terminate_stuff();
return 0;
}
Uncommenting data->frequency = 400; at least plays a 400hz sine wave, but that ignores any user input done in init_stuff()
If I put a printf("%f\n",data->frequency); inside the callback, it prints 0.000000 or something like -146730090609497866240.000000.
It's pretty unpredictable, and this really makes me think it's pointer related.
My goal for this code is to eventually incorporate envelope generators to change the pitch and possibly incorporate wavetable oscillators so I'm not calculating sin(x) for every iteration.
I can get envelopes and wavetables to work while using a blocking API like portsf that's used in the book, but trying to adapt any of that code from earlier chapters to use PortAudio callbacks is turning my brain to mush.
Thanks so much!
The problem you're having with your callback data is that it goes out of scope and memory is deallocated as soon as init_stuff finishes execution.
You should allocate memory for your callback data using malloc or new and passing the pointer to it for the callback.
For example:
void init_stuff()
{
float frequency;
int i;
PaStreamParameters outputParameters;
paTestData *data = (paTestData *) malloc(sizeof(paTestData));
printf("type the modulator frequency in Hz: ");
scanf("%f", &(data->frequency)); // get modulator frequency
printf("you chose data.frequency %.2f\n",data->frequency);
data->phase = 0.0;
...
Pa_OpenStream( // open paStream object
&audioStream, // portaudio stream object
NULL, // input params
&outputParameters, // output params
SAMPLING_RATE, // SampleRate
FRAME_BLOCK_LEN, // frames per buffer
paNoFlag, // set no Flag
audio_callback, // callbak function address
data );
...
I wasn't able to get the original code working using malloc but based on both suggestions, I realized another workable solution. Because running init_stuff() caused my data to get deallocated, I'm for now just making all my assignments and calls to Pa_OpenStream() from main.
Works beautifully and I can now send whatever data I want to the callback. Thanks for the help!
I have such code that is loading grayscale image from buffer 1byte, 8bits bitmap. Then it resizes this image.
int resizeBitmap(const unsigned char *inData, const size_t inDataLength, const size_t inWidth, const size_t inHeight,
const int bitDepth, const int noOfChannels, unsigned char **outData, size_t *outDataLength, const size_t outWidth, const size_t outHeight) {
// create input image
IplImage *inImage = cvCreateImage(cvSize(inWidth, inHeight), bitDepth, noOfChannels);
cvSetData(inImage, inData, inImage->widthStep);
// show input image
cvNamedWindow("OpenCV Input Image", CV_WINDOW_FREERATIO);
cvShowImage("OpenCV Input Image", inImage);
cvWaitKey(0);
cvDestroyWindow("OpenCV Input Image");
/* */
// create output image
IplImage *outImage = cvCreateImage(cvSize(outWidth, outHeight), inImage->depth, inImage->nChannels);
// select interpolation type
double scaleFactor = (((double) outWidth)/inWidth + ((double) outHeight)/inHeight)/2;
int interpolation = (scaleFactor > 1.0) ? CV_INTER_LINEAR : CV_INTER_AREA;
// resize from input image to output image
cvResize(inImage, outImage, interpolation);
/* // show output image
cvNamedWindow("OpenCV Output Image", CV_WINDOW_FREERATIO);
cvShowImage("OpenCV Output Image", outImage);
cvWaitKey(0);
cvDestroyWindow("OpenCV Output Image");
*/
// get raw data from output image
int step = 0;
CvSize size;
cvGetRawData(outImage, outData, &step, &size);
*outDataLength = step*size.height;
cvReleaseImage(&inImage);
cvReleaseImage(&outImage);
return 0;
}
I am using here bitDepth = 8 and noOfChannels = 1.
Loaded image is:
and the output is:
this output is not always written as program usually fails with error:
OpenCV Error: Bad number of channels (Source image must have 1, 3 or 4 channels) in cvConvertImage, file /tmp/opencv-20160915-26910-go28a5/opencv-2.4.13/modules/highgui/src/utils.cpp, line 611
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /tmp/opencv-20160915-26910-go28a5/opencv-2.4.13/modules/highgui/src/utils.cpp:611: error: (-15) Source image must have 1, 3 or 4 channels in function cvConvertImage
I am attaching debugger output as there is interesting situation as I am passing grayscale buffer of size 528480 which equals 1 byte * 1101 *480, but after cvCreateImage there is inside imageSize 529920 and widthStep is 1104! Maybe here is the problem with this image, but why it is ?
This issue is related to widthstep and width of IplImage. Opencv pads the image to have a widthstep of multiple of 4 bytes. Here opencv is using width of 1101 and widthstep of 1104. But data when written from bitmap to IplImage, few extra pixels get written per row(note the diagonal line from top-left to bottom-right).
Note, that the image is not tilted. It's just that every next row is shifted a little to left(by 3 pixels), thus giving the idea of shearing transformation.
It could also be possible that you are giving a smaller width than what Bitmap holds.
See docs here and search for padding. You can try copying all column data row-wise.
Why crash: Sometimes opencv will end up reading beyond Bitmap buffer and may hit untouchable memory addresses, causing exception.
Note: Bitmap probably also has padding from which you received the black diagonal line.
Based on answer saurabheights I have wrote procedure to make padding of each bitmap row to any given multiplicity of bytes in the row.
int padBitmap(const unsigned char *data, const size_t dataLength, const size_t width, const size_t height,
const int bitDepth, const int noOfChannels, unsigned char **paddedData, size_t *paddedDataLength, const size_t row_multiple) {
size_t row_length = (width*noOfChannels*bitDepth)/CHAR_BIT;
size_t row_padding_size = row_multiple - row_length % row_multiple;
if(row_padding_size == 0) return 0;
size_t new_row_length = row_length + row_padding_size;
size_t newDataLength = height * new_row_length;
unsigned char *newData = malloc(sizeof(unsigned char) *newDataLength);
unsigned char padding[3] = {0, 0, 0};
for(int i=0; i<height; i++) {
memcpy(newData + i*new_row_length, data + i*row_length, row_length);
memcpy(newData + i*new_row_length + row_length, padding, row_padding_size);
}
*paddedData = newData;
*paddedDataLength = newDataLength;
return row_padding_size;
}
Now before passing bitmap to resizeBitmap(), I am doing this padding:
unsigned char *paddedData = 0;
size_t paddedDataLength = 0;
int padding = padBitmap(gData, gDataLength, width, height, PNG_BIT_DEPTH_8, GRAYSCALE_COMPONENTS_PER_PIXEL, &paddedData, &paddedDataLength, 4);
width += padding;
And I am using as bitmap paddedData. It seems to work correctly
I created a program that embeds a message in a PPM file by messing with the last bit in each byte in the file. The problem I have right now is that I don't know if I am checking if a message is too long or not correctly. Here's what I've got so far:
int hide_message(const char *input_file_name, const char *message, const char *output_file_name)
{
unsigned char * data;
int n;
int width;
int height;
int max_color;
//n = 3 * width * height;
int code = load_ppm_image(input_file_name, &data, &n, &width, &height, &max_color);
if (code)
{
// return the appropriate error message if the image doesn't load correctly
return code;
}
int len_message;
int count = 0;
unsigned char letter;
// get the length of the message to be hidden
len_message = (int)strlen(message);
if (len_message > n/3)
{
fprintf(stderr, "The message is longer than the image can support\n");
return 4;
}
for(int j = 0; j < len_message; j++)
{
letter = message[j];
int mask = 0x80;
// loop through each byte
for(int k = 0; k < 8; k++)
{
if((letter & mask) == 0)
{
//set right most bit to 0
data[count] = 0xfe & data[count];
}
else
{
//set right most bit to 1
data[count] = 0x01 | data[count];
}
// shift the mask
mask = mask>>1 ;
count++;
}
}
// create the null character at the end of the message (00000000)
for(int b = 0; b < 8; b++){
data[count] = 0xfe & data[count];
count++;
}
// write a new image file with the message hidden in it
int code2 = write_ppm_image(output_file_name, data, n, width, height, max_color);
if (code2)
{
// return the appropriate error message if the image doesn't load correctly
return code2;
}
return 0;
}
So I'm checking to see if the length of the message (len_message) is longer that n/3, which is the same thing as width*height. Does that seem correct?
The check you're currently doing is checking whether the message has more bytes than the image has pixels. Because you're only using 1 bit per pixel to encode the message, you need to check if the message has more bits than the message has pixels.
So you need to do this:
if (len_message*8 > n/3)
In addition to #dbush's remarks about checking the number of bits in your message, you appear not to be accounting for all the bytes available to you in the image. Normal ("raw", P6-format) PPM images use three color samples per pixel, at either 8 or 16 bits per sample. Thus, the image contains at least 3 * width * height bytes of color data, and maybe as many as 6 * width * height.
On the other hand, the point of steganophraphy is to make the presence of a hidden message difficult to detect. In service to that objective, if you have a PPM with 16 bits per sample then you probably want to avoid modifying the more-significant bytes of the samples. Or if you don't care about that, then you might as well use the whole low-order byte of each sample in that case.
Additionally, PPM files record the maximum possible value of any sample, which does not need to be the same as the maximum value of the underlying type. It is possible for your technique to change the actual maximum value to be greater than the recorded maximum, and if you do not then change the maximum-value field as well then the inconsistency could be a tip-off that the file has been tampered with.
Furthermore, raw PPM format affords the possibility of multiple images of the same size in one file. The file header does not express how many there are, so you have to look at the file size to tell. You can use the bytes of every image in the file to hide your message.
I'm looking for a way to get the uncompressed stream size of an LZMA2 / .xz file compressed with the xz utility.
I'm using liblzma from Windows/Linux for this task, so I guess I'm looking for some C/C++ API in liblzma that will do the trick.
I think I've found a solution.
This is a very crude code sample, but seems to work fine.
I'm assuming I have a do_mmap() function that maps the entire file as read-only into memory, and returns the total size mapped.
This can naturally be adapted to use read/fread/ReadFile or any other File API.
extern size_t get_uncompressed_size(const char *filename)
{
lzma_stream_flags stream_flags;
int file_size;
const uint8_t *data = (uint8_t *) do_mmap(filename, &file_size);
// 12 is the size of the footer per the file-spec...
const uint8_t *footer_ptr = data + file_size - 12;
// Something is terribly wrong
if (footer_ptr < data) {
do_unmap((void *)data, file_size);
return -1;
}
// Decode the footer, so we have the backward_size pointing to the index
lzma_stream_footer_decode(&stream_flags, (const uint8_t *)footer_ptr);
// This is the index pointer, where the size is ultimately stored...
const uint8_t *index_ptr = footer_ptr - stream_flags.backward_size;
// Allocate an index
lzma_index *index = lzma_index_init(NULL);
uint64_t memlimit;
size_t in_pos = 0;
// decode the index we calculated
lzma_index_buffer_decode(&index, &memlimit, NULL, index_ptr, &in_pos, footer_ptr - index_ptr);
// Just make sure the whole index was decoded, otherwise, we might be
// dealing with something utterly corrupt
if (in_pos != stream_flags.backward_size) {
do_unmap((void *)data, file_size);
lzma_index_end(index, NULL);
return -1;
}
// Finally get the size
lzma_vli uSize = lzma_index_uncompressed_size(index);
lzma_index_end(index, NULL);
return (size_t) uSize;
}
Having downloaded the source from sourceforge and had a look here, I quoted this from the main header file LzmaLib.h
/*
LzmaUncompress
--------------
In:
dest - output data
destLen - output data size
src - input data
srcLen - input data size
Out:
destLen - processed output size
srcLen - processed input size
Returns:
SZ_OK - OK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation arror
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
*/
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize);
It looks that destLen is the size of the data that is uncompressed.