|
Yes indeed. In fact, as I recall the ILI9341 display adapter supports 18-bit color.
The place I had seen it before on the PC was the old VGA 320x200x8bpp mode where the 8 bit pixel was an indexed color into a palette. The palette colors were 18 bit.
Real programmers use butterflies
modified 12-Apr-21 11:01am.
|
|
|
|
|
Hi,I know 18bpp is used, I use it myself. The question was: Is there any hardware around that stores this information in a framebuffer every 2,25 bytes? I do not think so.
So I am not quite sure, what the use of this higly flexible pixel is. I can see a use for transforming of images. But the framebuffers I know are byte based and for performace reasons, aligned to byte, word or dword boundaries.
So when you do drawing, you can use an array (virtual area) of your pixels but I fear the performace would lack.
In a framebuffer, you normally have lots of pixels and it comes to processor cycles when you do drawing, copying, moving etc.. and want to get a useful frame rate So it is always nice if you can work with the register size of the CPU.
It sounds for me, that you plan to draw on a virtual area of pixels which are finally converted to the hardware equivalence in the framebuffer.
But maybe I did understand your problem wrong, that's why I asked for a code example.
|
|
|
|
|
I don't have the driver code built yet. I'm building the graphics end of it right now.
At any rate, supporting 18-bpp wasn't even my initial goal.
It's just that you can do this:
using bgr888 = pixel<
channel_traits<channel_name::B,8>,
channel_traits<channel_name::G,8>,
channel_traits<channel_name::R,8>
>;
using rgb565 = pixel<
channel_traits< channel_name::R,5>,
channel_traits<channel_name::G,6>,
channel_traits<channel_name::B,5>
>;
using gsc8 = pixel<
channel_traits<channel_name::L,8>
>;
using mono1 = pixel<
channel_traits<channel_name::L,1>
>;
using rgb888 = pixel<
channel_traits<channel_name::R,8>,
channel_traits<channel_name::G,8>,
channel_traits<channel_name::B,8>
>;
using rgb666 = pixel<
channel_traits<channel_name::R,6>,
channel_traits<channel_name::G,6>,
channel_traits<channel_name::B,6>
>;
using pixel_type = rgb666;
using bmp_type = bitmap<pixel_type>;
pixel_type p = color<pixel_type>::light_green;
uint8_t buf[bmp_type::sizeof_buffer(16,16)];
bmp_type bmp(16,16,buf);
bmp[point16(7,7)]=p;
p = bmp[point16(7,7)];
No matter how I declare a pixel, it has to work. The channel bit depths and even the number of channels and their types are arbitrary. The only thing above that even requires an RGB color model is the source colors like light_green above and they are convertible to the destination format in cases of black&white vs RGB
I think the ILI9341 doesn't align it's frame buffer in 18-bit mode, but I could be wrong.
Either way, it doesn't matter, since the above has to work.
(It's possible to add a NOP channel to a pixel, so I can pad out an 18-bit pixel to 24 bits)
Real programmers use butterflies
|
|
|
|
|
ok
|
|
|
|
|
The Univac 1100 series did, and 6 characters to a word.
|
|
|
|
|
Same with the PDP-10 when using SIXBIT[^]. I guess Univac did something similar.
|
|
|
|
|
What does that make a char in C?
6 bits?
I count on char being 8 bits in my code quite often.
Though to be fair when I do, it's usually uint8_t or int8_t that I'm using.
Who the elephant has time for a 6 bit character? I knew there were machines with unusual word sizes but this is ridiculous.
Real programmers use butterflies
|
|
|
|
|
Only those of us whose names end in -saurus wrote code for a PDP-10 or Univac.
The PDP-10's memory was limited to 256K words, so a little over 1MB. Hence things like SIXBIT.
I'm guessing that there were versions of C written for it while it was still in use, and a char must have been 8 bits. It did support ASCII, but I don't remember whether that was 7-bit or 8-bit.
|
|
|
|
|
Even in the gory days of hobby coding in the 80s I wasn't dealing with PDPs. Mostly it was 6502s or sometimes a fancy 16-bit 65c816.
Gotta be 8 bits or I'm done. I don't even want to deal with an architecture with a 6-bit word. Who designed it, the mayans?
Real programmers use butterflies
|
|
|
|
|
It was a DEC product. 8 bits hadn't become the de facto standard when it was developed.
|
|
|
|
|
Greg Utas wrote: Only those of us whose names end in -saurus wrote code for a PDP-10 or Univac.
Speak for yourself. I programmed a PDP-8 in University, and I'm not quite ready for the tar pits...
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
My university had one, but I never programmed it. A trophy for you because, if I remember correctly, PDP-8 was an appropriate name for a machine with only 8 opcodes!
|
|
|
|
|
IIRC, the minimum allowable character size in C is 5 bits. If your code relies on 'char' being 8 bits, you should really assert on CHAR_BIT (defined in limits.h).
Most programmers assume that "all the world's a Vax", and use 8-bit characters, 32-bit ints, etc. without a second thought.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
Typically i use int8_t if i need an 8 bit int
Real programmers use butterflies
|
|
|
|
|
It looks to me like it is the code that multiplies up the y direction. It seems to be giving values about 1/16 as large as they should be.
Good luck, brave programmer.
|
|
|
|
|
It was kind of. I was doing an add after a multiply instead of before it because I forgot some parens.
const size_t offs = ( (dstr.top()+dy)*dimensions().width+dstr.left() ) *pixel_type::bit_depth;
Real programmers use butterflies
|
|
|
|
|
It's the little things in life.
Jack of all trades, master of none, though often times better than master of one.
|
|
|
|
|
That describes much of programming perfectly!
|
|
|
|
|
Blowing a bit of smoke (pun?):
A few posters have shown discomfort with the idea of 2.25 bytes/pixel - I don't really understand their discomfort - the pixels are just there. Indeed, they are most easily grouped by the hardware/firmware in powers of two but that's only an artifact.
The problem, then, is that the artifact of basically all of our tools and abilities is geared towards powers of two and the data is not. Shyte, right ?
So, and here's the blowing smoke part - since you're going to commit a day of life to this (or so you threatened yourself). It's a matter of a proper set of masks - perched in an array that matches the pixel layout - but maybe the mask sizing should be larger than is usually intuitive. Find the lowest common multiple of 8 and 18 - and make that your mask size (at least to start) and then you simply (?) need to iterate through that array to isolate pixel (and/or their components).
You're much better at this than I, for sure, so the forgoing is an "out of the mouths of babes" type of suggestion.
Ravings en masse^ |
---|
"The difference between genius and stupidity is that genius has its limits." - Albert Einstein | "If you are searching for perfection in others, then you seek disappointment. If you seek perfection in yourself, then you will find failure." - Balboos HaGadol Mar 2010 |
|
|
|
|
|
Here's the thing. The # of channels per pixel, and the bit depth of each channel is arbitrary.
I could turn around right now and define a 19 bit pixel and the thing still needs to work.
So I have shifty bits in my code to ... shift bits. Also to set bits on non-byte boundaries.
static void shift_left(void* bits,size_t offset_bits,size_t size_bits, size_t shift) {
if(nullptr==bits || 0==size_bits || 0==shift) {
return;
}
if(shift>=size_bits) {
set_bits(bits,offset_bits,size_bits,false);
return;
}
uint8_t* pbegin = ((uint8_t*)bits)+(offset_bits/8);
const size_t offset = offset_bits % 8;
const size_t shift_bytes = shift / 8;
const size_t shift_bits = shift % 8;
const size_t overhang = (size_bits+offset_bits) % 8;
const uint8_t left_mask = ((uint8_t)uint8_t(0xFF<<(8-offset)));
const uint8_t right_mask = 0!=overhang?uint8_t(0xFF>>overhang):0;
uint8_t* pend = pbegin+(size_t)((offset_bits+size_bits)/8.0+.999999);
uint8_t* plast = pend-1;
uint8_t* psrc = pbegin+shift_bytes;
uint8_t* pdst = pbegin;
if(pbegin+1==pend) {
uint8_t save_mask = left_mask|right_mask;
uint8_t tmp = *pbegin;
*pbegin = uint8_t(uint8_t(tmp<<shift_bits)&~save_mask)|
uint8_t(tmp&save_mask);
return;
}
uint8_t left = *pbegin;
uint8_t right = *(pend-1);
while(pdst!=pend) {
uint8_t src = psrc<pend?*psrc:0;
uint8_t src2 = (psrc+1)<pend?*(psrc+1):0;
*pdst = (src<<shift_bits)|(src2>>(8-shift_bits));
++psrc;
++pdst;
}
*pbegin=(left&left_mask)|uint8_t(*pbegin&~left_mask);
--pend;
*plast=uint8_t(right&right_mask)|uint8_t(*plast&uint8_t(~right_mask));
};
I'll exclude shift_right, plus all the templatized versions of these functions that the compiler computes at compile time instead of run time
and
inline static void set_bits(size_t offset_bits,size_t size_bits,void* dst,const void* src) {
const size_t offset_bytes = offset_bits / 8;
const size_t offset = offset_bits % 8;
const size_t total_size_bytes = (offset_bits+size_bits)/8.0+.999999999;
const size_t overhang = (offset_bits+size_bits) % 8;
uint8_t* pbegin = ((uint8_t*)dst)+offset_bytes;
uint8_t* psbegin = ((uint8_t*)src)+offset_bytes;
uint8_t* pend = ((uint8_t*)dst)+total_size_bytes;
uint8_t* plast = pend-(pbegin!=pend);
const uint8_t maskL = 0!=offset?
(uint8_t)((uint8_t(0xFF>>offset))):
uint8_t(0xff);
const uint8_t maskR = 0!=overhang?
(uint8_t)~((uint8_t(0xFF>>overhang))):
uint8_t(0xFF);
if(pbegin==plast) {
uint8_t v = *psbegin;
const uint8_t mask = maskL & maskR;
v&=mask;
*pbegin&=~mask;
*pbegin|=v;
return;
}
*pbegin&=~maskL;
*pbegin|=((*psbegin)&maskL);
*plast&=~maskR;
*plast|=((*(psbegin+total_size_bytes-1))&maskR);
if(pbegin+1<plast) {
const size_t len = plast-(pbegin+1);
if(0!=len&&len<=total_size_bytes)
memcpy(pbegin+1,psbegin+1,len);
}
}
Real programmers use butterflies
|
|
|
|
|
honey the codewitch wrote: I needed a pair of parentheses. WELL, WELL, WELL!!!
If only someone had warned you about your poor usage of parenthesis!
|
|
|
|
|
Message Closed
modified 12-Apr-21 9:21am.
|
|
|
|
|
Please clarify. Are you interested in learning about general software development, or specifically in designing a new software language?
|
|
|
|
|
No need for clarification; his post is only there for the hidden spam link.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I can't find one, even when mousing around. What's your secret?
EDIT: Never mind. Found it.
modified 12-Apr-21 9:28am.
|
|
|
|
|