1800 views|0 replies

2015

Posts

0

Resources
The OP
 

TMS320C66x study notes TI official BMP reading program [Copy link]

The analysis program starts with mcip_bmp_utils.h, and pastes the BMP image file header definition. You can refer to this blog --- Image Processing and Pattern Recognition Classification ---- BMP File Structure to understand. It makes a good division of the file header structure and separates the subsequent operations. I think the most scientific thing is that it designed a raw image data structure raw_image_data_t. I didn’t quite understand this approach at first, but later I found that with it, the file acquisition and file decoding can be loosely coupled, so that the original data can be obtained from any form, such as TCP, camera, and file system. The versatility of the BMP image reading program module is improved. It is not only limited to soft simulation in CCS, but also can be separated from the PC through TCP, camera and other methods to obtain the original image data, and then perform BMP image decoding. #ifndef BMP_UTILS_H #define BMP_UTILS_H #include #include #include /****************************************************************************/ /* Bitmap file header structure*/ /********************************************************************************/ #ifdef _HOST_BUILD #pragma pack(1) #endif typedef struct bmpfile_signature { uint8_t signature[2]; /* Signature - 'BM' */ } bmpfile_signature_t; typedef struct bmpfile_header { uint32_t file_size; /* Size of the BMP image file*/ uint16_t reserved1; uint16_t reserved2; uint32_t bitmap_offset; /* Offset address of the BMP image data*/ } bmpfile_header_t; typedef struct bmpfile_dib_header { uint32_t header_size; /* Size of this structure*/ int32_t image_width; /* Width of the bitmap*/ int32_t image_height; /* Height of the bitmap*/ uint16_t number_of_planes; /* Number of planes */ uint16_t bits_per_pixel; /* Number of bits per pixel*/ uint32_t compression_type;/* Compression type*/ uint32_t image_size; /* Indicates the size of the bitmap data area in bytes*/ int32_t horizontal_resolution; /* Horizontal resolution, unit pixel/m */ int32_t vertical_resolution; /* Vertical resolution, unit pixel/m */ uint32_t number_of_colors; /* Colors used by the BMP image, 0 means using all colors, for a 256-color bitmap, this value is 100h=256 */ uint32_t important_color_count; /* Important color count */ } bmpfile_dib_header_t; typedef struct bmp_header { bmpfile_signature_t signature; bmpfile_header_t file; bmpfile_dib_header_t dib; } bmp_header_t; /************************************************************************/ /* Bitmap RGB palette entry structure*/ /********************************************************************************/ typedef struct { uint8_t red; uint8_t green; uint8_t blue; uint8_t reserved; } bmp_color_table_t; typedef enum { BMP_RGB = 0, BMP_RLE8, BMP_RLE4, BMP_BITFIELDS, BMP_JPEG, BMP_PNG } bmp_compression_method_e; /* Raw image data, needs to be decoded*/ typedef struct raw_image_data { uint8_t * data; uint32_t length; } get_raw_image_data_t(const char *_fname, const char *_mode); /*************************************************************************/ extern raw_image_data_t get_raw_image_data_from_file(const char *_fname, const char *_mode); /*************************************************************************/ /** * Created on: 2015-11-9 * Author: HeWu * This function is used to convert from raw data to bmp structure, * Parameter Description: raw_image_data_t * p_input_image raw byte data of the image * unsigned char * p_output_pixel_array pixel information of the image, used for subsequent processing * Return: raw_image_data_t structure * */ /*****************************************************************************/ extern int raw_data_cvt_bmp_pixels(raw_image_data_t * p_input_image,unsigned char * p_output_pixel_array); /****************************************************************************/ /* * * Function: This function reads the header information from a BMP file. * Description: The function does some preliminary checks on the file. * If the file is successfully read, it returns 0; * If the file is not read or the check fails, it returns a negative number. */ /************************************************************************************/ extern int bmp_read_header (raw_image_data_t * image, bmp_header_t * hdr); /*********************************************************************************/ /* * * Function Description: Read the color palette. This function is rarely used. The color palette is specific to monochrome, 16-color, and 256-color image files. * */ /*********************************************************************************/ extern int bmp_read_colormap (raw_image_data_t * image, bmp_header_t * hdr, bmp_color_table_t * color_table); /*****************************************************************************/ /* * * Function: Read the image (pixel value) and calculate the number of bytes occupied by the pixel. * Parameter description: raw_image_data_t * image, data to be decoded * bmp_header_t * hdr, file header * uint8_t * pixel_array_rgb, pointer to the returned pixel value, which is processed by the subsequent image algorithm*/ extern int bmp_read_image (raw_image_data_t * image, bmp_header_t * hdr, uint8_t * pixel_array_rgb); /*****************************************************************************/ /* * * Function function: Create and save pixel values as grayscale image through BMP image. /*****************************************************************************/ extern int bmp_write_gray_bmpfile (raw_image_data_t * image, uint8_t * pixel_array, uint32_t width, uint32_t height); /*****************************************************************************/ /* * Function: Get the file size of the grayscale BMP image*/ /*********************************************************************************/ extern uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height); #endif /*BMP_UTILS_H*/ get_raw_image_data_from_file(const char *_fname, const char *_mode); extern int raw_data_cvt_bmp_pixels(raw_image_data_t * p_input_image,unsigned char * p_output_pixel_array); These two functions should not be placed in this bmp reading module. They are written directly. The first one is to get the raw image data from the file system (it can also be obtained from other channels), and the second one is to decode the raw image into a pixel array (read the complete bmp_read_header() function first and then the bmp_read_image() function). The following is the implementation file of the mcip_bmp_utils.c function. /* =========================================================================/********************************************************************************/ /* * * Function Description: Read the color palette. This function is rarely used. The color palette is unique to monochrome, 16-color and 256-color image files. * */ /************************************************************************************/ extern int bmp_read_colormap (raw_image_data_t * image, bmp_header_t * hdr, bmp_color_table_t * color_table); /*****************************************************************************/ /* * * Function Function: Read the image (pixel value). You need to calculate the number of bytes occupied by the pixel. * Parameter description: raw_image_data_t * image, data to be decoded * bmp_header_t * hdr, file header * uint8_t * pixel_array_rgb, pointer to the returned pixel value, which is processed by the subsequent image algorithm*/ extern int bmp_read_image (raw_image_data_t * image, bmp_header_t * hdr, uint8_t * pixel_array_rgb); /*****************************************************************************/ /* * * Function function: Create and save pixel values as grayscale image through BMP image. /*****************************************************************************/ extern int bmp_write_gray_bmpfile (raw_image_data_t * image, uint8_t * pixel_array, uint32_t width, uint32_t height); /*****************************************************************************/ /* * Function: Get the file size of the grayscale BMP image*/ /*********************************************************************************/ extern uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height); #endif /*BMP_UTILS_H*/ get_raw_image_data_from_file(const char *_fname, const char *_mode); extern int raw_data_cvt_bmp_pixels(raw_image_data_t * p_input_image,unsigned char * p_output_pixel_array); These two functions should not be placed in this bmp reading module. They are written directly. The first one is to get the raw image data from the file system (it can also be obtained from other channels), and the second one is to decode the raw image into a pixel array (read the complete bmp_read_header() function first and then the bmp_read_image() function). The following is the implementation file of the mcip_bmp_utils.c function. /* =========================================================================/********************************************************************************/ /* * * Function Description: Read the color palette. This function is rarely used. The color palette is unique to monochrome, 16-color and 256-color image files. * */ /************************************************************************************/ extern int bmp_read_colormap (raw_image_data_t * image, bmp_header_t * hdr, bmp_color_table_t * color_table); /*****************************************************************************/ /* * * Function Function: Read the image (pixel value). You need to calculate the number of bytes occupied by the pixel. * Parameter description: raw_image_data_t * image, data to be decoded * bmp_header_t * hdr, file header * uint8_t * pixel_array_rgb, pointer to the returned pixel value, which is processed by the subsequent image algorithm*/ extern int bmp_read_image (raw_image_data_t * image, bmp_header_t * hdr, uint8_t * pixel_array_rgb); /*****************************************************************************/ /* * * Function function: Create and save pixel values as grayscale image through BMP image. /*****************************************************************************/ extern int bmp_write_gray_bmpfile (raw_image_data_t * image, uint8_t * pixel_array, uint32_t width, uint32_t height); /*****************************************************************************/ /* * Function: Get the file size of the grayscale BMP image*/ /*********************************************************************************/ extern uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height); #endif /*BMP_UTILS_H*/ get_raw_image_data_from_file(const char *_fname, const char *_mode); extern int raw_data_cvt_bmp_pixels(raw_image_data_t * p_input_image,unsigned char * p_output_pixel_array); These two functions should not be placed in this bmp reading module. They are written directly. The first one is to get the raw image data from the file system (it can also be obtained from other channels), and the second one is to decode the raw image into a pixel array (read the complete bmp_read_header() function first and then the bmp_read_image() function). The following is the implementation file of the mcip_bmp_utils.c function. /* =========================================================================uint8_t * pixel_array_rgb); /********************************************************************************/ /* * * Function: Create and save pixel values as a grayscale image through a BMP image. /*****************************************************************************/ extern int bmp_write_gray_bmpfile (raw_image_data_t * image, uint8_t * pixel_array, uint32_t width, uint32_t height); /*****************************************************************************/ /* * Function: Get the file size of the grayscale BMP image*/ /*********************************************************************************/ extern uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height); #endif /*BMP_UTILS_H*/ get_raw_image_data_from_file(const char *_fname, const char *_mode); extern int raw_data_cvt_bmp_pixels(raw_image_data_t * p_input_image,unsigned char * p_output_pixel_array); These two functions should not be placed in this bmp reading module. They are written directly. The first one is to get the raw image data from the file system (it can also be obtained from other channels), and the second one is to decode the raw image into a pixel array (read the complete bmp_read_header() function first and then the bmp_read_image() function). The following is the implementation file of the mcip_bmp_utils.c function. /* =========================================================================uint8_t * pixel_array_rgb); /********************************************************************************/ /* * * Function: Create and save pixel values as a grayscale image through a BMP image. /*****************************************************************************/ extern int bmp_write_gray_bmpfile (raw_image_data_t * image, uint8_t * pixel_array, uint32_t width, uint32_t height); /*****************************************************************************/ /* * Function: Get the file size of the grayscale BMP image*/ /*********************************************************************************/ extern uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height); #endif /*BMP_UTILS_H*/ get_raw_image_data_from_file(const char *_fname, const char *_mode); extern int raw_data_cvt_bmp_pixels(raw_image_data_t * p_input_image,unsigned char * p_output_pixel_array); These two functions should not be placed in this bmp reading module. They are written directly. The first one is to get the raw image data from the file system (it can also be obtained from other channels), and the second one is to decode the raw image into a pixel array (read the complete bmp_read_header() function first and then the bmp_read_image() function). The following is the implementation file of the mcip_bmp_utils.c function. /* ========================================================================= #include #include #include "mcip_bmp_utils.h" /*#define BMP_UTILS_DEBUG*/ /* BMP grayscale image default file header*/ static bmp_header_t default_grayscale_bmp_header = { { {'B', 'M'} /*signature*/ }, { 263222, /*file_size*/ 0, 0, /*reserved1, reserved2*/ 1078 /*bitmap_offset*/ }, { 40, /*header_size*/ 512, /*width*/ 512, /*height*/ 1, /*nplanes*/ 8, /*bitspp*/ 0, /*compress_type* / 262144, /*bmp_bytesz*/ 0, /*hres*/ 0, /*vres*/ 256, /*ncolors*/ 0 /*nimpcolors*/ } }; /*************************************** ******************************************/ /** * Created on: 2015-11-9 * Author: HeWu * This function is used to read the element data of a file from the file system. * The return type includes the byte data of the entire file and the byte length * */ /****** ************************************************** *********************/ raw_image_data_t get_raw_image_data_from_file(const char *_fname, const char *_mode) { Error_Block eb; Error_init(&eb); FILE * fpr = 0; raw_image_data_t raw_image = {0, 0}; uint32_t read_length = 0; int ret_val = 0; fpr = fopen(_fname, _mode); if(!fpr) { printf("Unable to open image file %s\n", _fname); } fseek(fpr, 0, SEEK_END); raw_image.length = ftell(fpr); fseek(fpr, 0, SEEK_SET); /** * The reason for using this Memory_alloc( ), instead of malloc(), * is to prevent memory fragmentation, or use the function provided by TI* */ raw_image.data = (uint8_t*)Memory_alloc(NULL,raw_image.length,0,&eb); if(! raw_image.data) { printf("Unable allocate buffer for raw image file read (%s)\n", _fname); } //fread() returns the number of bytes read, ret_val is used for pointer movement and Check do { ret_val = fread(raw_image.data + read_length, 1, raw_image.length - read_length, fpr); if (!ret_val) { printf("Unable read the raw image file %s\n", _fname); } read_length += ret_val; } while (read_length < raw_image.length); return raw_image;//Return raw image data} /************************ ************************************************** *******/ /** * Created on: 2015-11-9 * Author: HeWu * This function is used to convert from raw data to bmp structure, * the return type includes pixel data pointer * */ /* ************************************************** **************************/ extern int raw_data_cvt_bmp_pixels(raw_image_data_t * p_input_image,unsigned char * p_output_pixel_array) { Error_Block eb; Error_init(&eb); bmp_color_table_t * p_color_table = 0; bmp_header_t bmp_header; uint8_t * pixel_array_rgb = 0; int color_table_size,pixel_array_rgb_size; int pixel_size, row_width; int i, j, ret_val = 0; if ( (p_input_image == 0) || (p_input_image->length == 0) || (p_input_image->data == 0)) { printf("Invalid BMP image data\n"); ret_val = -1; return ret_val; } if (bmp_read_header(p_input_image, &bmp_header) < 0) { printf("Error in reading header\n"); ret_val = -1; return ret_val; } pixel_size = bmp_header.dib.bits_per_pixel / 8; //Number of bytes in a pixel row_width = bmp_header.dib.image_width * pixel_size; //Number of bytes in a row /* Read the palette, now Many bmp images do not have a palette, so you can ignore this part*/ if (bmp_header.dib.number_of_colors) { /* Color table present */ color_table_size = sizeof(bmp_color_table_t) * bmp_header.dib.number_of_colors; p_color_table = (bmp_color_table_t *) Memory_alloc(NULL,color_table_size,0,&eb); if(!p_color_table) { printf("Can't allocate memory for color table\n"); ret_val = -1; return ret_val; } if (bmp_read_colormap(p_input_image, &bmp_header, p_color_table) < 0) { printf("Error in reading color map\n"); ret_val = -1; return ret_val; } } /* Read pixel data, passed directly by the second parameter Pointer, no need to allocate memory here*/ if (bmp_read_image (p_input_image, &bmp_header, p_output_pixel_array) < 0) { printf("Error in reading pixel image\n"); ret_val = -1; return ret_val; } } /*** ************************************************** ***********************/ /* Read BMP information header*/ /********************* ************************************************** *********/ int bmp_read_header (raw_image_data_t * image, bmp_header_t * hdr) { /*If the file header structure is larger than the original image data size, it is an invalid image*/ if (image->length < sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + sizeof(bmpfile_dib_header_t)) { printf ("Insufficient Image Buffer Length % d\n", image->length); return -1; } /*Decode the original image data into three BMP file header structures*/ memcpy(&(hdr->signature), image->data, sizeof( bmpfile_signature_t)); memcpy(&(hdr->file), image->data + sizeof(bmpfile_signature_t), sizeof(bmpfile_header_t)); memcpy(&(hdr->dib), image->data + sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t),sizeof(bmpfile_dib_header_t)); /*Do some checks and read English yourself*/ if((hdr->signature.signature[0] != 'B') || (hdr->signature.signature[1] != 'M')) { printf("Incorrect MAGIC number 0x%x 0x%x\n", hdr->signature.signature[0], hdr->signature.signature[1]); return -1; } if((hdr->dib.bits_per_pixel != 8) && (hdr->dib.bits_per_pixel != 24)) { printf("Only 8 or 24 bits per pixel supported, the image bpp is %d\n", hdr->dib.bits_per_pixel); return -1; } if(hdr->dib.compression_type != BMP_RGB) { printf("Need a RGB type image, the image type is %d\n", hdr->dib.compression_type); return -1; } return 0; } /******** *************************************************** ******************/ /* Read BMP palette*/ /************************ *************************************************** *****/ int bmp_read_colormap (raw_image_data_t * image, bmp_header_t * hdr, bmp_color_table_t * color_table) { int index; if(hdr->dib.number_of_colors == 0) { printf("Color table can't be read, ncolors = %d\n", hdr->dib.number_of_colors ); return -1; } index = sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + hdr->dib.header_size; memcpy(color_table, image->data + index, sizeof(bmp_color_table_t) * hdr->dib.number_of_colors); #if BMP_UTILS_DEBUG { int i; printf("Color Table:\ nindex:\tblue\tgreen\tred\n"); for (i = 0; i < hdr->dib.number_of_colors; i++){ printf("%d:\t0x%02x\t0x%02x\t0x%02x\n", i, color_table[size=4 ].blue, color_table.green, color_table.red); } } #endif return 0; } /****************************************************** ***************************/ /*= BMP_RGB) { printf("Need a RGB type image, the image type is %d\n", hdr->dib.compression_type); return -1; } return 0; } /******** *************************************************** *****************/ /* Read BMP palette*/ /********************** *************************************************** ****/ int bmp_read_colormap (raw_image_data_t * image, bmp_header_t * hdr, bmp_color_table_t * color_table) { int index; if(hdr->dib.number_of_colors == 0) { printf("Color table can't be read, ncolors = %d\n", hdr->dib.number_of_colors ); return -1; } index = sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + hdr->dib.header_size; memcpy(color_table, image->data + index, sizeof(bmp_color_table_t) * hdr->dib.number_of_colors); #if BMP_UTILS_DEBUG { int i; printf("Color Table:\nindex:\tblue\ tgreen\tred\n"); for (i = 0; i < hdr->dib.number_of_colors; i++){ printf("%d:\t0x%02x\t0x%02x\t0x%02x\n", i, color_table.blue, color_table.green, color_table.red); } } #endif return 0; } /********************************************** ****************************/ /*= BMP_RGB) { printf("Need a RGB type image, the image type is %d\n", hdr->dib.compression_type); return -1; } return 0; } /******** *************************************************** *****************/ /* Read BMP palette*/ /************************ *************************************************** ****/ int bmp_read_colormap (raw_image_data_t * image, bmp_header_t * hdr, bmp_color_table_t * color_table) { int index; if(hdr->dib.number_of_colors == 0) { printf("Color table can't be read, ncolors = %d\n", hdr->dib.number_of_colors ); return -1; } index = sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + hdr->dib.header_size; memcpy(color_table, image->data + index, sizeof(bmp_color_table_t) * hdr->dib.number_of_colors); #if BMP_UTILS_DEBUG { int i; printf("Color Table:\nindex:\tblue\ tgreen\tred\n"); for (i = 0; i < hdr->dib.number_of_colors; i++){ printf("%d:\t0x%02x\t0x%02x\t0x%02x\n", i, color_table.blue, color_table.green, color_table.red); } } #endif return 0; } /************************************************ ****************************/ /*color_table.red); } } #endif return 0; } /************************ *************************************************** **/ /*color_table.red); } } #endif return 0; } /************************ *************************************************** **/ /* Read image (pixel value) */ /****************************************************************************/ int bmp_read_image (raw_image_data_t * image, bmp_header_t * hdr, uint8_t * pixel_array_rgb) { int i; int index; int pixel_size = hdr->dib.bits_per_pixel / 8;//Number of bytes per pixel int row_width = hdr->dib.image_width * pixel_size;//Number of bytes per row int row_width_with_pad = ((row_width) + 3) & (~3);//Don't understand here? Jump four bytes at once? Should it be alignment? _write_gray_bmpfile (raw_image_data_t * image, uint8_t * pixel_array, uint32_t width, uint32_t height) { int i; int index = 0; int row_width_with_pad = (width + 3) & (~3); int pad_size = row_width_with_pad - width; bmp_color_table_t * color_table = 0; uint8_t * pad_array = 0; bmp_header_t hdr = default_grayscale _bmp_header; int ret_val = 0; if(pad_size) { pad_array = calloc(pad_size, 1); } hdr.dib.image_height = height; hdr.dib.image_width = width; hdr.dib.image_size = (row_width_with_pad * hdr.dib.image_height); color_table = calloc(sizeof(bmp_color_table_t), hdr .dib.number_of_colors); for(i = 0; i < hdr.dib.number_of_colors; i++) { color_table.blue = i; color_table.green = i; color_table.red = i; } hdr.file.file_size = sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + hdr.dib.header_size + (sizeof(bmp_color_table_t) * hdr.dib.number_of_colors) + (row_width_with_pad * hdr.dib.image_height); hdr.file.bitmap_offset = sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + hdr.dib.header_size + (sizeof(bmp_color_table_t) * hdr.dib.number_of_colors); if (image->length < hdr.file.file_size) { printf("Insufficient image array size %d (expected %d)", image->length, hdr.file.file_size); ret_val = -1; goto close_n_exit; } memcpy(image->data, &hdr.signature,sizeof(bmpfile_signature_t)); index = sizeof(bmpfile_signature_t); memcpy(image->data + index, &hdr.file, sizeof(bmpfile_header_t)); index += sizeof(bmpfile_header_t); memcpy(image->data + index, &hdr .dib, sizeof(bmpfile_dib_header_t)); index += sizeof(bmpfile_dib_header_t); memcpy(image->data + index, color_table, sizeof(bmp_color_table_t) * hdr.dib.number_of_colors); index += sizeof(bmp_color_table_t) * hdr. dib.number_of_colors; for(i = hdr.dib.image_height - 1; i >= 0; i--) { memcpy(image->data + index, pixel_array + (hdr.dib.image_width * i), hdr.dib.image_width); index += hdr.dib.image_width; if (pad_size) { memcpy(image->data + index, pad_array, pad_size); index += pad_size; } } ret_val = 0; close_n_exit: if(color_table) free(color_table); if(pad_array) free(pad_array); return ret_val; } /************************ *************************************************** *******/ /* Get the file size of the grayscale image file*/ /********************************** ***********************************************/ uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height) { int row_width_with_pad = (width + 3) & (~3); /*Default bmp file header, modify some information, return the real image file size*/ bmp_header_t hdr = default_grayscale_bmp_header; return(sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + hdr.dib.header_size + (sizeof(bmp_color_table_t) * hdr.dib .number_of_colors) + (row_width_with_pad * height)); } I won't explain it here, just read the comments. if(color_table) free(color_table); if(pad_array) free(pad_array); return ret_val; } /****************************************************************************/ /* Get the file size of the grayscale image file*/ /****************************************************************************/ uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height) { int row_width_with_pad = (width + 3) & (~3); /*Default bmp file header, modify some information and return the actual image file size*/ bmp_header_t hdr = default_grayscale_bmp_header; return(sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + hdr.dib.header_size + (sizeof(bmp_color_table_t) * hdr.dib.number_of_colors) + (row_width_with_pad * height)); } I won't explain it here, just read the comments. if(color_table) free(color_table); if(pad_array) free(pad_array); return ret_val; } /****************************************************************************/ /* Get the file size of the grayscale image file*/ /****************************************************************************/ uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height) { int row_width_with_pad = (width + 3) & (~3); /*Default bmp file header, modify some information and return the actual image file size*/ bmp_header_t hdr = default_grayscale_bmp_header; return(sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + hdr.dib.header_size + (sizeof(bmp_color_table_t) * hdr.dib.number_of_colors) + (row_width_with_pad * height)); } I won't explain it here, just read the comments.
This post is from Microcontroller MCU
 

Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list