====== Velikosti slik ======
Večina oblik zapisa slik ima glavo, v kateri so zapisani tudi podatki o širini in višini slike.
===== PNG =====
Na osnovi [[https://stackoverflow.com/questions/54845745/not-able-to-read-ihdr-chunk-of-a-png-file|slike]] pridemo do velikosti slike takole:
> library(broman)
> f <- "../../pics/imfm.png"
> png <- file(f,"rb")
> s <- readBin(png,"raw",n=16)
> d <- hex2dec(readBin(png,"raw",n=8))
> w <- ((d[1]*256+d[2])*256+d[3])*256+d[4]
> h <- ((d[5]*256+d[6])*256+d[7])*256+d[8]
> cat("width =",w," height =",h,"\n")
width = 233 height = 160
> close(png)
Pri pripravi funkcije bi bilo potrebno dodati še preverjanje, ali gre res za zapis PNG.
Za večino ostalih zapisov slik gre podobno. Pri fotografijah so podatki o fotografiji pogosto zapisani v posebni obliki [[https://en.wikipedia.org/wiki/Exif|EXIF]].
===== JPEG =====
Pri zapisu JPEG je stvar nekoliko bolj zapletena, ker je ta sestavljen iz večih delov in je potrebno najprej najti pravi del in nato iz njega pobrati podatke o velikosti. Rešitev je že sprogramirana na [[https://web.archive.org/web/20131016210645/http://www.64lines.com/jpeg-width-height|spletu]]. Potrebno jo je bilo le prepisati v R:
> library(broman)
> # Gets the JPEG size from the array pic of data passed to the function,
> # file reference: http://www.obrador.com/essentialjpeg/headerinfo.htm
> # https://web.archive.org/web/20131016210645/http://www.64lines.com/jpeg-width-height
> get_jpeg_size <- function(pic) {
+ # Check for valid JPEG image
+ i=1 # Keeps track of the position within the file
+ size <- length(pic)
+ if((pic[i]==0xFF)&&(pic[i+1]==0xD8)&&(pic[i+2]==0xFF)&&(pic[i+3]==0xE0)) {
+ i <- i+4
+ # Check for valid JPEG header (null terminated JFIF)
+ if((rawToChar(pic[(i+2):(i+5)])=="JFIF")&&(pic[i+6]==0x00)) {
+ # Retrieve the block length of the first block since the first block will not contain the size of file
+ x <- hex2dec(pic[i:(i+1)]); blen = x[1]*256 + x[2]
+ while(i= size) return(c(0,0)) # Check to protect against segmentation faults
+ if(pic[i] != 0xFF) return(c(0,0)) # Check that we are truly at the start of another block
+ if(pic[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]
+ x <- hex2dec(pic[(i+5):(i+8)])
+ height <- x[1]*256 + x[2]; width <- x[3]*256 + x[4]
+ return(c(width,height))
+ }
+ else
+ {
+ i <- i+2 # Skip the block marker
+ x <- hex2dec(pic[i:(i+1)]); blen = x[1]*256 + x[2] # Go to the next block
+ }
+ }
+ return(c(0,0)) # If this point is reached then no size was found
+ }else{ return(c(0,0)) } # Not a valid JFIF string
+ }else{ return(c(0,0)) } # Not a valid SOI header
+ }
>
> f <- "C:/Users/vlado/pics/IMG_8191.jpg" # 1280 960
> jpg <- file(f,"rb")
> pic <- readBin(jpg,"raw",n=10^8); close(jpg)
> get_jpeg_size(pic)
[1] 1280 960