C - Bitmap creator



hi,  

i wrote the following piece code to create a new bitmap file with random RGB values. I wanted to copy the header from the input file.  

the problem is it adds two additional bytes to 3rd and 4th (just after the magic number). i can't figure out why.



// img.magic.magic[2] = 'G';  

// img.magic.magic[3] = 'Y';



if i uncomment the above lines. those bytes will be replaced by 'G' and 'Y'.



can anyone please explain me what's going on here?



thanks in advance.



```
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <unistd.h>

typedef struct bmpfile_magic {
	uint8_t magic[2];
} MAGIC;

typedef struct bmpfile_header {
	uint32_t filesz;
	uint16_t creator1;
	uint16_t creator2;
	uint32_t bmp_offset;
} BITMAPHEADER;

typedef struct {
	uint32_t header_sz;
	int32_t width;
	int32_t height;
	uint16_t nplanes;
	uint16_t bitspp;
	uint32_t compress_type;
	uint32_t bmp_bytesz;
	int32_t hres;
	int32_t vres;
	uint32_t ncolors;
	uint32_t nimpcolors;
} BITMAPINFOHEADER;

typedef struct {
	MAGIC magic;
	BITMAPHEADER head;
	BITMAPINFOHEADER infohead;
	int ***pixel;
} image;

int
main (int argc, char **argv)
{
	int fd;
	fd = open(argv[1], O_RDONLY);
	
	image img;
	
	ssize_t n;
	int val;
	
	// grabbing the header
	// magic numbers
	uint8_t v1;
	n = read(fd, &v1, 1);
	img.magic.magic[0] = v1;
	printf ("filetype: %c", img.magic.magic[0]);
	
	n = read(fd, &v1, 1);
	img.magic.magic[1] = v1;
	printf ("%c\n", img.magic.magic[1]);
	
	// img.magic.magic[2] = 'G';
	// img.magic.magic[3] = 'Y';
	
	// file size
	n = read(fd, &val, 4);
	img.head.filesz = val;
	printf ("file size: %"PRIu32"\n", img.head.filesz);
	
	// creator 1
	n = read(fd, &val, 2);
	img.head.creator1 = val;
	printf ("creator1: %d\n", img.head.creator1);
	
	// creator 2
	n = read(fd, &val, 2);
	img.head.creator2 = val;
	printf ("creator2: %d\n", img.head.creator2);
	
	// bitmap offset
	n = read(fd, &val, 4);
	img.head.bmp_offset = val;
	printf ("bitmap offset: %d\n", img.head.bmp_offset);
	
	// header size
	n = read(fd, &val, 4);
	img.infohead.header_sz = val;
	printf ("header size: %d\n", img.infohead.header_sz);
	
	// width
	n = read(fd, &val, 4);
	img.infohead.width = val;
	printf ("width: %d\n", img.infohead.width);
	
	// height
	n = read(fd, &val, 4);
	img.infohead.height = val;
	printf ("height: %d\n", img.infohead.height);
	
	// planes
	n = read(fd, &val, 2);
	img.infohead.nplanes = val;
	printf ("planes: %d\n", img.infohead.nplanes);
	
	// bits per pixel
	n = read(fd, &val, 2);
	img.infohead.bitspp = val;
	printf ("bits per pixel: %d\n", img.infohead.bitspp);
	
	// compression type
	n = read(fd, &val, 4);
	img.infohead.compress_type = val;
	printf ("compression type: %d\n", img.infohead.compress_type);
	
	// size of raw data including padding
	n = read(fd, &val, 4);
	img.infohead.bmp_bytesz = val;
	printf ("size of raw data(including padding): %d\n", img.infohead.bmp_bytesz);
	
	// horizontal resolution
	n = read(fd, &val, 4);
	img.infohead.hres = val;
	printf ("horizontal resolution: %d\n", img.infohead.hres);
	
	// vertical resolution
	n = read(fd, &val, 4);
	img.infohead.vres = val;
	printf ("horizontal resolution: %d\n", img.infohead.vres);
	
	// number of colors on the palette
	n = read(fd, &val, 4);
	img.infohead.ncolors = val;
	printf ("number of colors on the palette: %d\n", img.infohead.ncolors);
	
	// important colors
	n = read(fd, &val, 4);
	img.infohead.nimpcolors = val;
	printf ("important colors: %d\n", img.infohead.nimpcolors);
	
	// allocating memory dynamically
	img.pixel = malloc(img.infohead.height * sizeof(int *));
	
	int row, col, c, colors;
	// bits per pixel
	if (img.infohead.bitspp == 24) colors = 3; else colors = 4;
	
	// padding size
	int padding;
	padding = (img.infohead.bmp_bytesz - img.infohead.height*img.infohead.width*colors)/img.infohead.height;
	printf ("padding: %d\n", padding);
	
	for (row = 0; row < img.infohead.height; row++)
	{
		img.pixel[row] = malloc(img.infohead.width * sizeof(int *));
	}
	
	for (row = 0; row < img.infohead.height; row++)
		for (col = 0; col < img.infohead.width; col++)
		{
			img.pixel[row][col] = malloc(colors * sizeof(int *));
		}
	
	// reading data
	off_t pos = lseek(fd, img.head.bmp_offset, SEEK_SET);
	
	for (row = img.infohead.height-1; row >= 0; row--)
		for (col = 0; col < img.infohead.width; col++)
			for (c = 0; c < colors; c++)
			{
				img.pixel[row][col][c] = (rand () % 255) + 0;
			}
	
	// write the new file
	FILE *fp2;
	fp2 = fopen(argv[2], "w");
	
	ssize_t nn;
	//nn = write(fd2, &img, img.head.bmp_offset-1);
	
	fwrite(&img, img.head.bmp_offset, 1, fp2);
	
	for (row = 0; row < img.infohead.height; row++)
		for (col = 0; col < img.infohead.width; col++)
			for (c = 0; c < colors; c++)
			{
				printf ("img.pixel[%d][%d][%d]: %d\n", row, col, c, img.pixel[row][col][c]);
				
			}
	
	close(fd);
	fclose(fp2);
	
	exit(EXIT_SUCCESS);
}
```
The compiler aligns BITMAPHEADER at a 4-byte boundary. Since MAGIC occupies only 2 bytes, the compiler (when laying out the image structure) inserts 2 bytes of padding between `magic` and `head` .
> 
> But how is this achieved?
> 
> 
> 


The system is not perfect. I personally do not like a lot of dumb decisions they made. But the basic idea is that they have:


* A catalog of consistent **printed** colors.
* A set of base colors and the **formulas** to achive the derivated colors.
* The base colors have some **specific values on colorimetry** that are repeatable by diferent manufacturers of inks.



> 
> I assume there are no "Pantone Inks", right?
> 
> 
> 


Yes and no. **Pantone is the system** to have a consistent color. Then, diferent **ink manufacturers** make a set of base inks based on the specifications.


So a manufacturer "HappyInks Inc." make an ink, for example "Pantone Reflex Blue"


**Printers** then go to the formula guide to find the recipy for the colors on the catalog, and go and buy from "Happy Inks" the basic set of colors.


They combine "Pantone Reflex Blue" with "Pantone Sunrise Yellow" in some specified proportions (from the pantone formula guide) to achive "Green XXXc".


If you are going to need a lot of ink of one specific color, the printer do not mix the base inks themselves, but ask for "Happy Inks" to make them some kilos of the ink (based, again on the pantone specifications).


The quality of diferent brands can be more or less accurate. Besides that some characteristics of inks can differ because some could be oriented to silk print, or textiles etc.



> 
> the printer needs in RGB.
> 
> 
> 


This is a biiiiiig mistake.


RGB is not by any means an acurate color reference. Either your printer is lazy or he is simply using some kind of digital print (but still is ignorant(*).


You need to include a RGB profile. Either sRGB or Adobe 1998 but you need to design using a CMYK profile, which obviously you do not have. So ask for which one is more suitable for that.


If they have no idea or say something like "It does not matter" use one according to your location. SWOP 2, Fogra, Gracol, etc.



> 
> Will the colours vary too much if using a Pantone - RGB convertor?
> 
> 
> 


If the project is on flat inks, the proper step would be that you deliver a project in Pantone and let them do the conversions, so they are responsable to match the color the best way possible.


This is why I say they are Ignorant. (*) They ignore what is the calibration of their own machine. They should profile it and give you some clues on what "generic profile" suits them the most.



> 
> textile print
> 
> 
> 


This does not say much. Are you printing rolls and rolls of fabric? Are you printing a Tshirt on a digital medium, like a logo for a student party? Are you using silk print for the campain for a company?


**An Aditional note**



> 
> will the colours vary too much
> 
> 
> 


Colors vary for a looooooooot of reasons.


My clasic example, grab a water based cyan marker. You have a specific ink one and only one.


Now go an paint everywhere you want. A news paper, a magazine, a window, a white towel, toilet paper, your hand.


See? The exact same ink vary a lot. This is why you must have an output color profile, so this gives the internal conversions and calculations to have the most acurate color possible due this combination of factors, which color on which medium.


This is why the printer should be responsable for the color conversions.


**Aditional Note 2**


There are some conversions from pantone to cmyk and rgb... Ouch.


This are very specific conversions. On some "ideal" situations.


More or less how an ink will be printed following exact specifications, for example a CMYK: type of paper, type of inks, controlled ammount of them (densitometry), etc.


For an RGB one they assume a calibrated monitor, Correct gamma, correct temperature, sRGB profile. But again this rgb simulation is for output for a web page for example, not as a printable file.


Spot color (Pantone), or Color selection (CMYK)



Depending on the type of design you have the choice to print in either of this 2 color modes.


For example, a design with gradients and diferent colors most likely needs to be printed in color selection.


But some other type of design needs to be printed with spot inks, or direct colors, this reduces costs and aditionally allow the colors to be consistent


[![](https://otake.com.mx/Foros/Directa.jpg)](https://otake.com.mx/Foros/Directa.jpg) Hi mgfranz,We are happy to announce the release of Photoshop CC 19.1.5.This update includes the fix for [Photoshop CC 2018: An integer between 96 and 8 is required. Closest value inserted. "Could not complete your request bec…](https://community.adobe.com/external-link.jspa?url=https%3A%2F%2Ffeedback.photoshop.com%2Fphotoshop_family%2Ftopics%2Fphotoshop-cc-2018-an-integer-between-96-and-8-is-required-closest-value-inserted)Once the update is installed, to allow Photoshop to manage memory the temporary fix needs to be removed.See this: [Error while accessing performance preferences - 'An integer between 96 and 8 is required.'](https://community.adobe.com/external-link.jspa?url=https%3A%2F%2Fhelpx.adobe.com%2Fphotoshop%2Fkb%2Finvalid-numeric-entry-integer-96-8-required-photoshop.html)Here's a list of what's new in this release: [Fixed issues in Adobe Photoshop CC](https://community.adobe.com/external-link.jspa?url=https%3A%2F%2Fhelpx.adobe.com%2Fphotoshop%2Fkb%2Ffixed-issues.html)... After 5 hours of learning I have compiled these:


Mindset



1. **Make sure the placed image ratio is good** to make it more realistic. This can be attained by checking with the other object in the output picture, like trees, or other peoples' height. You are not going to place human with the size much smaller than the other human at the same picture. Similarly, you also must not place a person with the height higher than a tree.
2. **Get the right perspective**. Sometimes, when an object is placed in an odd perspective, image is going to look very bold that it has been photoshopped or copy pasted.
3. **Lighting**. It is important to pay attention to light source, like the sun, and make sure our object is appropriate with output background light source. This can be done by adjusting the lighting of object and adding shadow with referencing other shadow in output image.


Tools (to make edges more realistic)



1. **Layer masking.** If moving people, hair can look awful if just plainly moved. Masking allows us to further tweak our selection.
2. **Refine edge.** *This tool allows you to control many aspect of the edge of your selection* (desired object to move), like Edge Detection (brushing the edges of object and let photoshop do its job, usually around dog fur), Feather (Soften the area of selection), Smooth (reduce pointiness of your selection), Contrast (somewhat opposite of smooth), and Shift Edge (moving feather far or nearer the selection, usually to remove excess background color near the edges). *REFERENCE: <https://www.youtube.com/watch?v=5lDr2Nd8Yl4>*
3. **Layer Matting**. Inside we have many sub-tools to work on, like Color Decontamination (spread out soft mask around the edge, usually for hair to catch other hair that accidentally masked or can be used similarly to Shift Edge), Remove Matte (soften edge of sharp graphic or pixalated, raster look). *REFERENCE: <https://www.youtube.com/watch?v=N6K_htNQPPA>*
4. **Image Calculation**. By playing with the blending, we can make the background darker; thus, helping us making mask. *REFERENCE: <https://www.youtube.com/watch?v=0zf-H9RoCNk>* Unicode can be a problem, and Perl has its own quirks. Essentially, Perl creates a firewall that surrounds all Unicode I / O capabilities. You must tell Perl if the I / O path is encoded. If so, the DECODE rule for any input and / or ENCODE for any output.


Decoding converts the data from {encoding} to Perl's internal representation, which is probably a combination of bytes and code points.


The coding is just the opposite.


Thus, it is actually possible to "decode into" and "encode" up to two different encodings. You just need to say what it is. Encoding / decoding is usually done with the file I / O layer, but you can use the encoding module (distribution part) to manually convert between encodings.


 [perldocs in Unicode](https://translate.googleusercontent.com/translate_c?depth=1&pto=aue&rurl=translate.google.com&sl=ru&sp=nmt4&tl=en&u=) does not read light.



  




 (adsbygoogle = window.adsbygoogle || []).push({});
 
  

Here's an example that can help visualize it (there are many other ways).



```
use strict;
use warnings;
use Encode;


# This is an internalized string with these UTF-8 codepoints
# 
my $internal_string_1 = "\x{C7}\x{69}\x{64}\x{65}\x{6D}\x{5F}\x{15E}\x{65}\x{6E}\x{65}\x{72}\x{20}\x{48}\x{FC}\x{73}\x{6E}\x{FC}\x{20}\x{54}\x{61}\x{11F}\x{6C}\x{69}\x{70}";


# Open a temp file for writing as UTF-8.
# Output to this file will be automatically encoded from Perl internal to UTF-8 octets.
# Write the internal string.
# Check the file with a UTF-8 editor.
# 
open (my $out, '>:utf8', 'temp.txt') or die "can't open temp.txt for writing $!";
print $out $internal_string_1;
close $out;


# Open the temp file for readin as UTF-8.
# All input from this file will be automatically decoded as UTF-8 octets to Perl internal.
# Read/decode to a different internal string.
# 
open (my $in, '<:utf8', 'temp.txt') or die "can't open temp.txt for reading $!";
$/ = undef;
my $internal_string_2 = <$in>;
close $in;


# Change the binmode of STDOUT to UTF-8.
# Output to STDOUT will now be automatically encoded from Perl internal to UTF-8 octets.
# Capture STDOUT to a file then check with a UTF-8 editor.
# 
binmode STDOUT, ':utf8';
print $internal_string_2, "\n\n";


# Use encode() to convert an internal string to UTF-8 octets
# Format the UTF-8 octets to hex values
# Print to STDOUT
# 
my $octets = encode ("utf8", $internal_string_2);
print "Encoded (out) string -> UTF-8 (octets):\n";
print " length = ".length($octets)."\n";
print " octets = $octets\n";
print " HEX val = ";
for (split //, $octets) {
    printf ("0x%X ", ord($_));
}
print "\n\n";


# Use decode() to convert external UTF-8 octets to an internal string.
# Format the internal string to codepoints (hex values).
# Print to STDOUT.
# 
my $internal_string_3 = decode ("utf8", $octets);
print "Decoded (in) string <- UTF-8 (octets):\n";
print " length = ".length($internal_string_3)."\n";
print " string = $internal\_string\_3\n";
print " code points = ";
for (split //, $internal_string_3) {
    printf ("\\x{%X} ", ord($_));
}

        

        
        
        
 (adsbygoogle = window.adsbygoogle || []).push({});
 
        

    
```

Output



```
Çidem\_Şener Hüsnü Tağlip

Encoded (out) string -> UTF-8 (octets):
   length  =  29
   octets  =  Ãidem\_Åener HÃ¼snÃ¼ TaÄlip
   HEX val = 0xC3 0x87 0x69 0x64 0x65 0x6D 0x5F 0xC5 0x9E 0x65 0x6E 0x65 0x72 0x20 0x48 0xC3 0xBC 0x73 0x6E 0xC3 0xBC 0x20 0x54 0x61 0xC4 0x9F 0x6C 0x69 0x70

Decoded (in) string <- UTF-8 (octets):
   length      =  24
   string      =  Çidem\_Şener Hüsnü Tağlip
   code points = \x{C7} \x{69} \x{64} \x{65} \x{6D} \x{5F} \x{15E} \x{65} \x{6E} \x{65} \x{72} \x{20} \x{48} \x{FC} \x{73} \x{6E} \x{FC} \x{20} \x{54} \x{61} \x{11F} \x{6C} \x{69} \x{70}

        

        
        
        
 (adsbygoogle = window.adsbygoogle || []).push({});
 
        

    
``` I used [an automatic photoshop script](http://arnaumarch.com/en/sprites.html) once and worked well.


The concept is : 


* Each portion is a different image.
* Each portion (and so, each images) must be in the same folder w/o any other images.
* Run the script indicating the folder and some parameters (size, css name, etc...).
* The script does : 


	1. Merge all images into one with the size you indicated.
	2. Generate the CSS file


In your case, if you modify one image, you regenerate the global image and the CSS via the script and... that's it. Maybe you'll need to copy/paste the CSS in yours if you don't want to use the generated one.


Notes :


I tried it with a few files and worked great. Then, I tried like ~600 pictures and then, you'll need a goooood CPU and patience ;) In this case, don't use it. the code you posted above still has the original img tag with joy.jpg, so it doesn't show what you entered that did not work.
but taking a wild guess, i would point out that javascript is case-sensitive, and so is the challenge checker, so if you accidentally substituted lower case for upper case, or vice-versa, it would not work in the code or pass the challenge. you can use the repmat function here
if you have to print the patter n (here 10) times, use the following code:
a = [5 4 3 2 1 0]';
n = 10;
b =repmat(a, n,1) The older Brightness and Contrast effect does not work in 32-bit float, as you can see in the Effects tab ... the GPU accelerated lego is there but not the 32-bit lego block. That means that it is doing all processing in 8 bit ... while say Lumetri works in 32 bit float. It can make a difference in how fast and how bad banding appears. Not that working in Lumetri will "cure" the banding, but it could easily be less with Lumetri. I don't know why anyone goes into the Effects panel for the old... ![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)

 Write your answer Hi Jan,


years ago John Hawkinson did a script that would invoke the place options on an already placed PDF, InDesign page or AI file, I think. Hope, I can find the old thread or the ExtendScript code. You could build on this. But be warned: Not all PDFs would show how many pages are inside. At least you cannot see this by scripting.


 


Ah. Found the extended script I did, based on John's original one:


 


 



```
// PlaceAgain-PlaceOptionsShowing-SELECTION.jsx
// Uwe Laubender

//DESCRIPTION:Select a placed image, PDF or InDesign document to replace it with itself getting options

/**
* @@@BUILDINFO@@@ PlaceAgain-PlaceOptionsShowing-SELECTION.jsx !Version! Fri Sep 09 2016 14:09:53 GMT+0200
*/

/*
	Posted in this thread at Adobe InDesign Forum:
	"Toggle pages of a linked Indesign document inside Indesign?"
	mmackinven | Sep 9, 2016
	https://forums.adobe.com/message/8993859#8993859
	
	You can either select the placed file directly or its container frame.
	Or, if its part of a group, the group itself.
	Or, if the container frame is pasted inside another object, that object.
	
*/

placeAgainSelection();

function placeAgainSelection()
{
	if(app.documents.length == 0){alert("ERROR"+"\r"+"No document is open."); return};
	if(app.selection.length != 1){alert("ERROR"+"\r"+"Select one single item containing a placed file."); return};

	// The placed object is selected:
	if
	(
		app.selection[0].constructor.name == "ImportedPage" || 
		app.selection[0].constructor.name == "PDF" ||
		app.selection[0].constructor.name == "EPS" ||
		app.selection[0].constructor.name == "Image" ||
		app.selection[0].constructor.name == "PICT" ||
		app.selection[0].constructor.name == "WMF"
	)
	{	
		var graphic = app.selection[0];
	};
	
	else if(app.selection[0].allGraphics.length == 0){return};
	
	// The container of the placed object is selected:
	else{var graphic = app.selection[0].allGraphics[0]};

	// Two important checks:
	// Case 1: Graphic was pasted on the page from e.g. PhotoShop:
	if(graphic.itemLink == null){alert("ERROR"+"\r"+"The graphic was pasted on the page. The original file cannot be found.");return};
	// Case 2: Link is not available, because placed graphic was renamed, removed or otherwise is not available:
	var file = File(graphic.itemLink.filePath);
	if(!file.exists){alert("ERROR"+"\r"+"\""+file.name+"\""+"\r"+"File cannot be found."); return};
	
	// If you cancel the place options dialog, no error will be thrown:
	try{
	graphic.place(file,true);
	}catch(e){};
};
```

 


 


**Important Note:**


The original thread from 2016 where I posted the script code did not make it to the new InDesign forum.


 


Because of that this thread where I mentioned my script is rendered useless:


[https://community.adobe.com/t5/indesign/swapping-pages-of-a-linked-file-indesign-file-without-replac...](https://community.adobe.com/t5/indesign/swapping-pages-of-a-linked-file-indesign-file-without-replacing-the-file-and-choosing-the-page/m-p/10403771?page=1)


 


This one as well, but there is also a link to a script by Roland Dreger that could be useful:


<https://community.adobe.com/t5/indesign/linked-ai-file-change-artboard/m-p/10444575?page=1>


 


Regards,  
Uwe Laubender


( ACP )