生成.ppm格式棋盘格图像仅特定Tile尺寸生效的问题求助
棋盘格PPM图像生成程序的Tile宽度异常问题
我编写了一个C程序,用于生成指定长宽、Tile尺寸及双色的.ppm格式棋盘格图像。程序使用一维size_t数组按行优先存储RGB像素值(每个像素包含3个取值范围为[0,255]的整数,数组总长度为像素数的3倍)。
我尝试过多种实现方式:单循环结合模运算填充像素、逐Tile填充等,最终选择逐行从上到下填充的方式。调试后发现程序存在异常:
- Tile高度参数任意值均能正常工作
- Tile宽度参数仅为20或100时,500x500的图像生成正确;即使是500的因数(如10、25、250等)也无法正常生成,表现为Tile高度显示异常
程序为确定性实现,相同输入输出一致,无非法指针操作或未初始化变量,已尝试重启系统排查。未在相关技术平台找到解决方案。以下是Tile宽度设为25时的代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define IMAGE_SIZE_X 500 #define IMAGE_SIZE_Y 500 #define IMAGE_ARRAY_SIZE 3*IMAGE_SIZE_X*IMAGE_SIZE_Y #define MAX_PIXEL_VALUE 255 /* Creates a .ppm binary image file, given a file path (relative or absolute) with the file extension, and two positive integer dimensions (horizontal and vertical pixels), a positive maximum pixel color value (commonly 255), and a one-dimensional array of non-negative integers representing RGB (red, green blue) pixel values, in that order. Returns EXIT_SUCCESS on success. If a file with the given path already exists, the file is overwritten. If the file could not be opened for writing, errno is set, an error message is printed to stderr, and EXIT_FAILURE is returned. If the file could not be closed properly, errno is set, and EXIT_FAILURE is returned. */ int write_ppm(const char* filepath, size_t* pic, const size_t size_x, const size_t size_y, const size_t maxval) { // open the file as a binary file, create the file first if it does not exist FILE *fp = fopen(filepath, "wb"); if(!fp) { fprintf(stderr, "Failed to open file named \"%s\" for writing\n", filepath); return EXIT_FAILURE; } // header fprintf(fp, "P6\n%zu %zu\n%zu\n", size_x, size_y, maxval); // populate the RGB pixel values for(size_t i = 0; i < 3*size_x*size_y; i+=3) fprintf(fp, "%c%c%c", (unsigned char) pic[i], (unsigned char) pic[i+1], (unsigned char) pic[i+2]); // close the file if(fclose(fp) != 0) return EXIT_FAILURE; else return EXIT_SUCCESS; } // create a checkerboard pattern on an array representing a .ppm file, // given two colors and the two side lengths of the checkerboard tiles void checkerboard_ppm(size_t* pic, const size_t size_x, const size_t size_y, const size_t color0[3], const size_t color1[3], const size_t tileLength_x, const size_t tileLength_y) { int color = 0; for(size_t row = 0; row < size_y; row++) { for(size_t col = 3*size_x*row; col < 3*size_x*(row+1); col += 3) { // swap colors when reaching the rightmost part of a tile, // but not at the right edge of the image if(((col/3) % tileLength_x == 0) && ((col/3) % size_x != 0)) color = 1 - color; if(color == 0) { pic[col] = color0[0]; pic[col + 1] = color0[1]; pic[col + 2] = color0[2]; } else { pic[col] = color1[0]; pic[col + 1] = color1[1]; pic[col + 2] = color1[2]; } } // swap colors after writing a number of rows equal to the tile height if((row + 1) % tileLength_y == 0) color = 1 - color; } } int main() { const size_t RED [3] = {255, 0, 0}, BLUE [3] = { 0, 0, 255}; size_t image[IMAGE_ARRAY_SIZE]; checkerboard_ppm(image, IMAGE_SIZE_X, IMAGE_SIZE_Y, RED, BLUE, 25, 20); write_ppm("output.ppm", image, IMAGE_SIZE_X, IMAGE_SIZE_Y, MAX_PIXEL_VALUE); return EXIT_SUCCESS; }
内容的提问来源于stack exchange,提问作者Adam El-Sawaf
相关产品推荐
相关产品推荐

