Getting Image size of JPEG from its binary - file

I have a lot of jpeg files with varying image size. For instance, here is the first 640 bytes as given by hexdump of an image of size 256*384(pixels):
0000000: ffd8 ffe0 0010 4a46 4946 0001 0101 0048 ......JFIF.....H
0000010: 0048 0000 ffdb 0043 0003 0202 0302 0203 .H.....C........
0000020: 0303 0304 0303 0405 0805 0504 0405 0a07 ................
0000030: 0706 080c 0a0c 0c0b 0a0b 0b0d 0e12 100d ................
I guess the size information mus be within these lines. But am unable to see which bytes give the sizes correctly. Can anyone help me find the fields that contains the size information?

According to the Syntax and structure section of the JPEG page on wikipedia, the width and height of the image don't seem to be stored in the image itself -- or, at least, not in a way that's quite easy to find.
Still, quoting from JPEG image compression FAQ, part 1/2 :
Subject: [22] How can my program extract image dimensions from a JPEG
file?
The header of a JPEG file consists of
a series of blocks, called "markers".
The image height and width are stored
in a marker of type SOFn (Start Of
Frame, type N). To find the SOFn
you must skip over the preceding
markers; you don't have to know what's
in the other types of markers, just
use their length words to skip over
them. The minimum logic needed is
perhaps a page of C code. (Some
people have recommended just searching
for the byte pair representing SOFn,
without paying attention to the marker
block structure. This is unsafe
because a prior marker might contain
the SOFn pattern, either by chance or
because it contains a JPEG-compressed
thumbnail image. If you don't follow
the marker structure you will retrieve
the thumbnail's size instead of the
main image size.) A profusely
commented example in C can be found in
rdjpgcom.c in the IJG distribution
(see part 2, item 15). Perl code
can be found in wwwis, from
http://www.tardis.ed.ac.uk/~ark/wwwis/.
(Ergh, that link seems broken...)
Here's a portion of C code that could help you, though : Decoding the width and height of a JPEG (JFIF) file

This function will read JPEG properties
function jpegProps(data) { // data is an array of bytes
var off = 0;
while(off<data.length) {
while(data[off]==0xff) off++;
var mrkr = data[off]; off++;
if(mrkr==0xd8) continue; // SOI
if(mrkr==0xd9) break; // EOI
if(0xd0<=mrkr && mrkr<=0xd7) continue;
if(mrkr==0x01) continue; // TEM
var len = (data[off]<<8) | data[off+1]; off+=2;
if(mrkr==0xc0) return {
bpc : data[off], // precission (bits per channel)
h : (data[off+1]<<8) | data[off+2],
w : (data[off+3]<<8) | data[off+4],
cps : data[off+5] // number of color components
}
off+=len-2;
}
}
 

I have converted the CPP code from the top answer into a python script.
"""
Source: https://stackoverflow.com/questions/2517854/getting-image-size-of-jpeg-from-its-binary#:~:text=The%20header%20of%20a%20JPEG,Of%20Frame%2C%20type%20N).
"""
def get_jpeg_size(data):
"""
Gets the JPEG size from the array of data passed to the function, file reference: http:#www.obrador.com/essentialjpeg/headerinfo.htm
"""
data_size=len(data)
#Check for valid JPEG image
i=0 # Keeps track of the position within the file
if(data[i] == 0xFF and data[i+1] == 0xD8 and data[i+2] == 0xFF and data[i+3] == 0xE0):
# Check for valid JPEG header (null terminated JFIF)
i += 4
if(data[i+2] == ord('J') and data[i+3] == ord('F') and data[i+4] == ord('I') and data[i+5] == ord('F') and data[i+6] == 0x00):
#Retrieve the block length of the first block since the first block will not contain the size of file
block_length = data[i] * 256 + data[i+1]
while (i<data_size):
i+=block_length #Increase the file index to get to the next block
if(i >= data_size): return False; #Check to protect against segmentation faults
if(data[i] != 0xFF): return False; #Check that we are truly at the start of another block
if(data[i+1] == 0xC0): #0xFFC0 is the "Start of frame" marker which contains the file size
#The structure of the 0xFFC0 block is quite simple [0xFFC0][ushort length][uchar precision][ushort x][ushort y]
height = data[i+5]*256 + data[i+6];
width = data[i+7]*256 + data[i+8];
return height, width
else:
i+=2; #Skip the block marker
block_length = data[i] * 256 + data[i+1] #Go to the next block
return False #If this point is reached then no size was found
else:
return False #Not a valid JFIF string
else:
return False #Not a valid SOI header
with open('path/to/file.jpg','rb') as handle:
data = handle.read()
h, w = get_jpeg_size(data)
print(s)

This is how I implemented this using js. The marker you are looking for is the Sofn marker and the pseudocode would basically be:
start from the first byte
the beginning of a segment will always be FF followed by another byte indicating marker type (those 2 bytes are called the marker)
if that other byte is 01 or D1 through D9, there is no data in that segment, so proceed to next segment
if that marker is C0 or C2 (or any other Cn, more detail in the comments of the code), thats the Sofn marker you're looking for
the following bytes after the marker will be P (1 byte), L (2 bytes), Height (2 bytes), Width (2 bytes) respectively
otherwise, the next two bytes followed by it will be the length property (length of entire segment excluding the marker, 2 bytes), use that to skip to the next segment
repeat until you find the Sofn marker
function getJpgSize(hexArr) {
let i = 0;
let marker = '';
while (i < hexArr.length) {
//ff always start a marker,
//something's really wrong if the first btye isn't ff
if (hexArr[i] !== 'ff') {
console.log(i);
throw new Error('aaaaaaa');
}
//get the second byte of the marker, which indicates the marker type
marker = hexArr[++i];
//these are segments that don't have any data stored in it, thus only 2 bytes
//01 and D1 through D9
if (marker === '01' || (!isNaN(parseInt(marker[1])) && marker[0] === 'd')) {
i++;
continue;
}
/*
sofn marker: https://www.w3.org/Graphics/JPEG/itu-t81.pdf pg 36
INFORMATION TECHNOLOGY –
DIGITAL COMPRESSION AND CODING
OF CONTINUOUS-TONE STILL IMAGES –
REQUIREMENTS AND GUIDELINES
basically, sofn (start of frame, type n) segment contains information
about the characteristics of the jpg
the marker is followed by:
- Lf [frame header length], two bytes
- P [sample precision], one byte
- Y [number of lines in the src img], two bytes, which is essentially the height
- X [number of samples per line], two bytes, which is essentially the width
... [other parameters]
sofn marker codes: https://www.digicamsoft.com/itu/itu-t81-36.html
apparently there are other sofn markers but these two the most common ones
*/
if (marker === 'c0' || marker === 'c2') {
break;
}
//2 bytes specifying length of the segment (length excludes marker)
//jumps to the next seg
i += parseInt(hexArr.slice(i + 1, i + 3).join(''), 16) + 1;
}
const size = {
height: parseInt(hexArr.slice(i + 4, i + 6).join(''), 16),
width: parseInt(hexArr.slice(i + 6, i + 8).join(''), 16),
};
return size;
}

If you are on a linux system and have PHP at hand, variations on this php script may produce what you are looking for:
#! /usr/bin/php -q
<?php
if (file_exists($argv[1]) ) {
$targetfile = $argv[1];
// get info on uploaded file residing in the /var/tmp directory:
$safefile = escapeshellcmd($targetfile);
$getinfo = `/usr/bin/identify $safefile`;
$imginfo = preg_split("/\s+/",$getinfo);
$ftype = strtolower($imginfo[1]);
$fsize = $imginfo[2];
switch($fsize) {
case 0:
print "FAILED\n";
break;
default:
print $safefile.'|'.$ftype.'|'.$fsize."|\n";
}
}
// eof
host> imageinfo 009140_DJI_0007.JPG
009140_DJI_0007.JPG|jpeg|4000x3000|
(Outputs filename, file type, file dimensions in pipe-delimited format)
From the man page:
For more information about the 'identify' command, point your browser to [...] http://www.imagemagick.org/script/identify.php.

Dart/Flutter port from a solution in this forum.
class JpegProps {
final int precision;
final int height;
final int width;
final int compression;
JpegProps._(this.precision, this.height, this.width, this.compression,);
String toString() => 'JpegProps($precision,$height,$width,$compression)';
static JpegProps readImage(Uint8List imageData) {
// data is an array of bytes
int offset = 0;
while (offset < imageData.length) {
while (imageData[offset] == 0xff) offset++;
var mrkr = imageData[offset];
offset++;
if (mrkr == 0xd8) continue; // SOI
if (mrkr == 0xd9) break; // EOI
if (0xd0 <= mrkr && mrkr <= 0xd7) continue;
if (mrkr == 0x01) continue; // TEM
var length = (imageData[offset] << 8) | imageData[offset + 1];
offset += 2;
if (mrkr == 0xc0) {
return JpegProps._(imageData[offset],
(imageData[offset + 1] << 8) | imageData[offset + 2],
(imageData[offset + 3] << 8) | imageData[offset + 4],
imageData[offset + 5],
);
}
offset += length - 2;
}
throw '';
}
}

Easy way to get width and heigh from a .jpg picture. Remove the EXIF and ITP information in the the file. Use "Save as" function in a view picture program (I used IrfanView or Pain Shop Pro). In the "Save as" get rid of EXIF, then save the file. The jpg file has always without EXIF the heigh at byte 000000a3 and 000000a4. The width are at 000000a5 and 000000a6
I use php
function storrelse_jpg($billedfil) //billedfil danish for picturefile
{
//Adresse for jpg fil without EXIF info !!!!!
// width is in byte 165 til 166, heigh is in byte 163 og 164
// jpg dimensions are with 2 bytes ( in png are the dimensions with 4 bytes
$billedfil="../diashow/billeder/christiansdal_teltplads_1_x.jpg"; // the picturefil
$tekst=file_get_contents($billedfil,0,NULL,165,2); //Read from 165 2 bytes - width
$tekst1=file_get_contents($billedfil,0,NULL,163,2);//Read from 163 2 bytes - heigh
$n=strlen($tekst); // længden af strengen
echo "Størrelse på billed : ".$billedfil. "<br>"; // Headline
$bredde=0; // width
$langde=0; // heigh
for ($i=0;$i<$n;$i++)
{
$by=bin2hex($tekst[$i]); //width-byte from binær to hex
$bz=hexdec($by);// then from hex to decimal
$ly=bin2hex($tekst1[$i]); // the same for length byte
$lz=hexdec($ly);
$bredde=$bredde+$bz*256**(1-$i);
$langde=$langde+$lz*256**(1-$i);
}
// $x is a array $x[0] er width and $x[1] er heigh
$x[0]=$bredde; $x[1]=$langde;
return $x;
}

A python solution based on "raw" CPP convert - https://stackoverflow.com/a/62245035/11807679
def get_jpeg_resolution(image_bytes: bytes,
size: int = None) -> Optional[Tuple[int, int]]:
"""
function for getting resolution from binary
:param image_bytes: image binary
:param size: image_bytes len if value is None it'll calc inside
:return: (width, height) or None if not found
"""
size = len(image_bytes) if size is None else size
header_bytes = (0xff, 0xD8, 0xff, 0xe0)
if not (size > 11
and header_bytes == struct.unpack_from('>4B', image_bytes)):
# Incorrect header or minimal length
return None
jfif_bytes = tuple(ord(s) for s in 'JFIF') + (0x0, )
if not (jfif_bytes == struct.unpack_from('5B', image_bytes, 6)):
# Not a valid JFIF string
return None
index = len(header_bytes)
block_length, = struct.unpack_from(">H", image_bytes, index)
index += block_length
while index < size:
if image_bytes[index] != 0xFF:
break
# Check that we are truly at the start
# of another block
if image_bytes[index + 1] == 0xC0:
# 0xFFC0 is the "Start of frame" marker
# which contains the file size
# The structure of the 0xFFC0 block is
# quite simple
# [0xFFC0][ushort length][uchar precision]
# [ushort x][ushort y]
height, width = struct.unpack_from(">HH", image_bytes, index + 5)
return width, height
else:
index += 2
# Skip the block marker
# Go to the next block
block_length, = struct.unpack(">H",
image_bytes[slice(index, index + 2)])
# Increase the file index to get to the next block
index += block_length
# If this point is reached then no size was found
return None

Related

Processing YUV I420 from framebuffer?

I have a byte array named buf, that contains a single video frame in YUV I420 format obtained from a framebuffer. For every video frame I also have the following information:
Size (e.g. 320x180)
Stride Y (e.g. 384)
Stride U (e.g. 384)
Stride V (e.g. 384)
Plane offset Y (e.g. 0)
Plane offset U (e.g. 69120)
Plane offset V (e.g. 69312)
Concatenating multiple video frames in a file, and passing that with size information to a raw video decoder in VLC or FFmpeg just produces garbled colors, so I think the bytes in buf should be reordered using the information above to produce playable output, but I'm completely new to working with video so this may be wrong.
I which order should size, stride and offset information be combined with bytes in buf to produce a byte stream that could be played raw in a video player?
Example:
https://transfer.sh/E8LNy5/69518644-example-01.yuv
The layout of the data seems odd but using the given offsets and strides, this is decodable as YUV.
First there are 384 * 180 bytes of luma.
Following are the chroma lines, each being 192 bytes long... but U and V lines take turns! This is accounted for by the strange offsets. U offset points exactly to after luma. V offset is 192 bytes further... and reading would leapfrog by 384 bytes.
Here's code that extracts those planes and assembles them as I420, for decoding with cvtColor:
#!/usr/bin/env python3
import numpy as np
import cv2 as cv
def extract(data, offset, stride, width, height):
data = data[offset:] # skip to...
data = data[:height * stride] # get `height` lines
data.shape = (height, stride)
return data[:, :width] # drop overscan/padding
width, height = 320, 180
Yoffset = 0
Uoffset = 69120 # 384*180
Voffset = 69312 # 384*180 + 192
Ystride = 384
Ustride = 384
Vstride = 384
data = np.fromfile("69518644-example-01.yuv", dtype=np.uint8)
Y = extract(data, Yoffset, Ystride, width, height)
U = extract(data, Uoffset, Ustride, width // 2, height // 2)
V = extract(data, Voffset, Vstride, width // 2, height // 2)
# construct I420: Y,U,V planes in order
i420 = np.concatenate([Y.flat, U.flat, V.flat])
i420.shape = (height * 3 // 2, width)
result = cv.cvtColor(i420, cv.COLOR_YUV2BGR_I420)
cv.namedWindow("result", cv.WINDOW_NORMAL)
cv.resizeWindow("result", width * 4, height * 4)
cv.imshow("result", result)
cv.waitKey()
cv.destroyAllWindows()

Determine if a message is too long to embed in an image

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.

Why is my bitmap drawing function plotting at an offset from the position I give it? (C VGA Mode 12h)

Hello I´m working on creating a bitmap drawing function on C using VGA in mode 12h using DOSBOX to run the program. I´m getting the image on the screen, but the start of the image is being drawn on the middle on the screen instead of (0,0). Can anyone tell me why I´m getting this behavior?
My plot_pixel function works fine. I´m able to draw lines and plot pixels on the screen without getting the weird offset I´m getting now.
This shows the problem.
Original Image:
Result:
And this is my code:
Load BMP:
/**************************************************************************
* load_bmp *
* Loads a bitmap file into memory. *
**************************************************************************/
void load_bmp(char *file, BITMAP *b){
FILE *fp;
long index;
byte a;
word num_colors;
int x;
//SetGfxMode(0x3);
/*Opening file */
if((fp = fopen(file,"rb")) == NULL){
printf("Error al abrir el archivo %s.\n",file);
exit(1);
}
/*Validating if the image is a valid bitmap*/
if(fgetc(fp) != 'B' || fgetc(fp) != 'M'){
fclose(fp);
printf("%s is not a bitmap file. \n", file);
exit(1);
}
/*Height and width of the image
*/
fskip(fp,16);
fread(&b->width, sizeof(word),1 , fp);
fskip(fp,2);
fread(&b->height, sizeof(word),1,fp);
fskip(fp,22);
fread(&num_colors,sizeof(word),1,fp);
fskip(fp,6);
/* We are loading a 16 color image */
if(num_colors ==0) num_colors = 16;
/*Intentamos alojar memoria para la data del bitmap*/
if((b->data = (byte *) malloc((b->width*b->height))) == NULL)
{
fclose(fp);
printf("Error allocating memory for file %s.\n",file);
exit(1);
}
/*Reading pallete info*/
for(index=0;index<num_colors;index++){
b->pallete[(int)(index*3+2)] = fgetc(fp) >> 2;
b->pallete[(int)(index*3+1)] = fgetc(fp) >> 2;
b->pallete[(int)(index*3+0)] = fgetc(fp) >> 2;
//fskip(fp,240);
x = fgetc(fp);
}
/* Leyendo el bitmap*/
for(index=(b->height-1)*b->width;index>=0;index-=b->width){
for(x=0;x<b->width;x++){
b->data[index+x]=(byte)fgetc(fp);
}
}
fclose(fp);
}
Draw bitmap:
/**************************************************************************
* draw_transparent_bitmap *
* Draws a transparent bitmap. *
**************************************************************************/
void draw_transparent_bitmap(BITMAP *bmp,int x,int y)
{
int i,j;
unsigned long bitmap_offset = 0;
byte data;
copyMemory(double_buffer,VGA);
printf("sum");
getch();
for(j=0;j<bmp->height;j++)
{
for(i=0;i<bmp->width;i++)
{
data = bmp->data[bitmap_offset];
//if (data) double_buffer[screen_offset+x+i] = data;
if(data) plot_pixel(x+i,y+j,data);
bitmap_offset++;
}
}
}
Set Pallete
void set_pallete(byte *pallete){
int i;
outp(PALETTE_INDEX,0);
for(i=0;i<16*3;i++){
outp(PALETTE_DATA,pallete[i]);
}
}
Main:
typedef struct
{
word width;
word height;
byte pallete[256*3];
byte *data;
} BITMAP;
BITMAP fondo_inicio;
load_bmp("home16.bmp",&fondo_inicio);
set_pallete(fondo_inicio.pallete);
draw_transparent_bitmap(&fondo_inicio,0,0);
I'm not persuaded you're loading the BMP correctly. Per Wikipedia, which hopefully managed to get this right as a rare all-but-objective fact, your code, after you've checked for 'BM', assuming fskip is some sort of spin on fseek, takes these steps:
skip the 4 bytes telling you BMP size;
skip the 4 reserved bytes;
skip the 4 bytes telling you where you should load pixel data from (which you really should consume and obey);
assume you're getting a Windows 3.1 secondary header and skip the 4 bytes tell you its length (you shouldn't);
read the lower two bytes of width;
skip the upper two bytes of width;
read the lower two bytes of height;
skip the upper two bytes of height;
skip: number of colour planes (+ 2 bytes), bits per pixel (+ 2 bytes), compression method (+ 4 = 10), image size (+ 4 = 14), horizontal density (+ 4 = 18), vertical density (+4 = 22);
read first two bytes of colour palette size;
skip next two bytes of colour palette size;
skip number of important colours;
assume the headers have then ended (but you should instead have read the header size and skipped appropriate here);
reads an RGBA palette, assuming it knows the image to be 16-colour, discarding the alpha and mapping from 8 bits-per-channel to VGA-style 6 bits;
assume the image data comes straight after the palette (you shouldn't, you should have read its file offset earlier);
read one byte per pixel of image data. Even though you've assumed 4 bits per pixel for reading the palette.
Likely your BMP file isn't 4-bit if reading a whole byte per pixel is providing the correct width of image. That means your assumptions about header size are definitely wrong. Almost certainly what you have stored as the image data is a chunk of header and then the image. Start by not skipping the header entry that tells you where image data begins — read it and use it. Otherwise if your plot_pixel automatically maps eight bits to four then it's not a big problem if you're loading a 256-colour image and assuming that only the lowest sixteen colours are used, assuming that holds true of your source imagery and storage space isn't a concern.

unable to loop through data in c pos

I am new to POS programming using C language. I want to loop through the returned hex data and also print it to the screen after sending the APDU command and getting a response. Here is my main problem requirements.
First I elect the EMV Application using PSE method 1PAY.SYS.DD01
I read the record of the PSE which returns me the AID
I select the AID currently I'm using cards with VISA AIDs (A0 00 00 00 03 10 10 and A0 00 00 00 03 20 10)
3.I read the record of the AID interestingly for the first AID, it returns the magnetic stripe info without using GPO command first while the second one for some cards it requires them so I next get the GPO to process it
I then read the records from the card. The problem is I am outputting this byte info so its easy for me to track what's going on but the POS terminal I am using can only output a given number of characters on the screen. First I have space for 18 bytes, then I can have up to maximum of 35 bytes to display after clearing the screen everytime the user presses the arrow down button.
To do this, I used some variables below
int variab = 0,
offset = 18,
remainingBytes = apduResp.LenOut - 18,
limit = apduResp.LenOut,
AIDChooser = 0; // To track output data scroll
// option
if (apduResp.LenOut == 0)
{
offset = 0;
remainingBytes = 0;
limit = 0;
}
else if (apduResp.LenOut > 0)
{
int variab = 0,
offset = 18,
remainingBytes = apduResp.LenOut - 18,
limit = apduResp.LenOut,
AIDChooser = 0;
}
Then I put the code below in a loop that runs while the arrow down key is pressed I read all the data and this is what it is supposed to do
i) Read all response bytes and the length
ii) check if the remaining bytes are more than 35, add 35 to the loop offset and then print the next 35 up to the limit which is (offset + 35). and if the remaining bytes are less than 35, print them out and stop.
The problem is when the intial data length is 0, pressing the scroll button doesn't show subsequent data but if the initial response data is greater than zero, the function works as required, can anyone figure out what I'm doing wrong?
if (remainingBytes > 35)
{
limit = offset + 35;
for (i_sn = offset; i_sn < limit; i_sn++)
{
sn_display += sprintf(sn_display, "%02X ", `apduResp.DataOut[i_sn]);
TP_LcdPrintf(" %s", te);
}
offset = limit; // Change
// offset
remainingBytes = apduResp.LenOut - limit; // Reduce
// remaining bytes
}
else if (remainingBytes == 0)
{
TP_LcdPrintf(" %s", " No more data\n Press Cancel to\n return");
}
else if (remainingBytes > 0 && remainingBytes < 35)
{
for (i_sn = offset; i_sn < apduResp.LenOut; i_sn++)
{
sn_display += sprintf(sn_display, "%02X ", apduResp.DataOut[i_sn]);
TP_LcdPrintf(" %s", te);
}
offset = limit;
remainingBytes = apduResp.LenOut - limit;
}
////indent: Standard input:32: Error:Stmt nesting error.
}
… in the first block of code you have under #5, you have some variables you are initializing in the else part of an if statement that are declared, initialized, but then never used. So their values will not be "seen" outside of that if statement block because their scope is all inside else { ... } – lurker

Get the character dominant from a string

Okay.. according to the title i am trying to figure out a way - function that returns the character that dominates in a string. I might be able to figure it out.. but it seems something is wrong with my logic and i failed on this. IF someome can come up with this without problems i will be extremelly glad thank you.
I say "in a string" to make it more simplified. I am actually doing that from a buffered data containing a BMP image. Trying to output the base color (the dominant pixel).
What i have for now is that unfinished function i started:
RGB
bitfox_get_primecolor_direct
(char *FILE_NAME)
{
dword size = bmp_dgets(FILE_NAME, byte);
FILE* fp = fopen(convert(FILE_NAME), "r");
BYTE *PIX_ARRAY = malloc(size-54+1), *PIX_CUR = calloc(sizeof(RGB), sizeof(BYTE));
dword readed, i, l;
RGB color, prime_color;
fseek(fp, 54, SEEK_SET); readed = fread(PIX_ARRAY, 1, size-54, fp);
for(i = 54; i<size-54; i+=3)
{
color = bitfox_pixel_init(PIXEL_ARRAY[i], PIXEL_ARRAY[i+1], PIXEL_ARRAY[i+2);
memmove(PIX_CUR, color, sizeof(RGB));
for(l = 54; l<size-54; l+=3)
{
if (PIX_CUR[2] == PIXEL_ARRAY[l] && PIX_CUR[1] == PIXEL_ARRAY[l+1] &&
PIX_CUR[0] == PIXEL_ARRAY[l+2])
{
}
Note that RGB is a struct containing 3 bytes (R, G and B).
I know thats nothing but.. thats all i have for now.
Is there any way i can finish this?
If you want this done fast throw a stack of RAM at it (if available, of course). You can use a large direct-lookup table with the RGB trio to manufacture a sequence of 24bit indexes into a contiguous array of counters. In partial-pseudo, partial code, something like this:
// create a zero-filled 2^24 array of unsigned counters.
uint32_t *counts = calloc(256*256*256, sizeof(*counts));
uint32_t max_count = 0
// enumerate your buffer of RGB values, three bytes at a time:
unsigned char rgb[3];
while (getNextRGB(src, rgb)) // returns false when no more data.
{
uint32_t idx = (((uint32_t)rgb[0]) << 16) | (((uint32_t)rgb[1]) << 8) | (uint32_t)rgb[2];
if (++counts[idx] > max_count)
max_count = idx;
}
R = (max_count >> 16) & 0xFF;
G = (max_count >> 8) & 0xFF;
B = max_count & 0xFF;
// free when you have no more images to process. for each new
// image you can memset the buffer to zero and reset the max
// for a fresh start.
free(counts);
Thats it. If you can afford to throw a big hulk of memory at this a (it would be 64MB in this case, at 4 bytes per entry at 16.7M entries), then performing this becomes O(N). If you have a succession of images to process you can simply memset() the array back to zeros, clear max_count, and repeat for each additional file. Finally, don't forget to free your memory when finished.
Best of luck.

Resources