"TheEndless" wrote:
"destruk" wrote:
It just seems like an entirely too much amount of work to do something which could easily be incorporated into a core component like - copytojpg, or copytopng to convert bitmap data roku or a server already has direct access to to begin with.
You won't get any arguments there. It's definitely something that would be best to be implemented in the core. The fact that someone actually took the time to port a PNG library to Brightscript might be enough to convince Roku it's necessary. It eventually happened with the JSON libraries we all put together, so maybe....
I agree, would be very nice to have. A way to access pixels directly would be even nicer. I originally was looking into it as a way to use a PNG like framebuffer for doing pixel plotting but it is slower then doing a DrawRect(x ,y , 1, 1, &hFF) etc. Also would be nice to have access to an audio buffer for building sound samples, multithreading
🙂 Even better would be to just have homebrew access to the 3D roku sdk .
I have done some more work on the encoder and checked my changes into github. I have combined all the loops into one function and added/modified the adler32/crc32 function to take a byte at a time.
https://github.com/GPF/pngEncodeRokufunction IDATChunk(width as integer,height as integer,pixels as object) as object
chunk = CreateObject("roByteArray")
chunk.push(0)'placeholder for idat size
chunk.push(0)'placeholder for idat size
chunk.push(0)'placeholder for idat size
chunk.push(0)'placeholder for idat size
n=ADLER32calc()
c=rdCRC()
y=0
x=0
f=0
BLOCK_SIZE = 32000
zlength=BLOCK_SIZE
id=asc("I"):chunk.push(id):c.updateOneCRC(id)
id=asc("D"):chunk.push(id):c.updateOneCRC(id)
id=asc("A"):chunk.push(id):c.updateOneCRC(id)
id=asc("T"):chunk.push(id):c.updateOneCRC(id)
'Zlib Header
id=8:chunk.push(id):c.updateOneCRC(id):f=f+1 ' CM = 8, CMINFO = 0
id=(31 - ( (8*2^8) MOD 31 ) ) MOD 31:chunk.push(id):c.updateOneCRC(id):f=f+1 ' FCHECK (FDICT/FLEVEL=0)
for i = 0 to pixels.count()-1
if ((y+x) MOD (BLOCK_SIZE)) =0 then
if (( pixels.count()-y) < BLOCK_SIZE) then
zlength=(pixels.count()-y)+(height-x)
id=1:chunk.push(id):c.updateOneCRC(id):f=f+1 ' Final flag, Compression type
print "y= "+y.toStr()
else
id=0:chunk.push(id):c.updateOneCRC(id):f=f+1 ' Final flag, Compression type
print "lasty= "+y.toStr()
endif
print "zlength= "+zlength.toStr()
id=(zlength and &HFF):chunk.push(id):c.updateOneCRC(id):f=f+1 ' Length LSB
id=((zlength and &HFF00)/256):chunk.push(id):c.updateOneCRC(id):f=f+1 ' Length MSB
id=( (NOT zlength) and &HFF):chunk.push(id):c.updateOneCRC(id):f=f+1 ' Length 1st complement LSB
id=( ( (NOT zlength) and &HFF00)/256) ' Length 1st complement MSB
chunk.push(id):c.updateOneCRC(id):f=f+1
endif
if(y MOD (width*4)) =0 then
id=0:chunk.push(id):c.updateOneCRC(id):n.UpdateAdler(id):f=f+1 'no Filter
x=x+1
endif
id=pixels[i]:chunk.push(id):
c.updateOneCRC(id):n.UpdateAdler(id):f=f+1
y=y+1
endfor
ad=n.TotalAdler()
temp = CreateObject("roByteArray")
temp = rdINTtoBA(ad)
id=temp[0]:chunk.push(id):c.updateOneCRC(id):f=f+1
id=temp[1]:chunk.push(id):c.updateOneCRC(id):f=f+1
id=temp[2]:chunk.push(id):c.updateOneCRC(id):f=f+1
id=temp[3]:chunk.push(id):c.updateOneCRC(id):f=f+1
datsize=rdINTtoBA(f) 'idat size
chunk[0]=datsize[0]
chunk[1]=datsize[1]
chunk[2]=datsize[2]
chunk[3]=datsize[3]
chunk.append(rdINTtoBA(not (c.TotalOneCRC() ) ))
return chunk
end function
function ADLER32calc() as object
this = {
'Member vars
s1%:1
s2%:0
'Methods
ResetAdler: function () as integer
m.s1%=1
m.s2%=0
end function
UpdateAdler: function (abs% as integer)
m.s1% = (m.s1% + abs%) MOD 65521
m.s2% = (m.s2% + m.s1%) MOD 65521
end function
TotalAdler: function () as integer
return (m.s2%*65536) + m.s1%
end function
}
return this
end function
updateOneCRC: function(buf as integer)
crc=m.TheCRC
t = m.CRCTABLE
index = ((crc and not buf) or (not crc and buf)) and &hFF
shiftedc = ((crc and &hFFFFFF00)/256) and &hFFFFFF
m.TheCRC= ((shiftedc and not t[index]) or (not shiftedc and t[index]))
end function
TotalOneCRC: function() as integer
return m.TheCRC
end function