📄 eprnfs.c
字号:
int colorant, correction, error, new_value, pixel, pixel_mod_8, pixels = line->length/OCTETS_PER_PIXEL, plane, remaining_error; eprn_Octet approx, *from, *ptr[4], *to; for (plane = 0; plane < PLANES; plane++) ptr[plane] = bitplanes[plane].str; /* Loop over pixels in the scan line. Note that 'pixels' may increase within the loop. */ for (pixel = 0, pixel_mod_8 = 8; pixel < pixels; pixel++, pixel_mod_8++) { if (pixel_mod_8 == 8) { pixel_mod_8 = 0; for (plane = 0; plane < PLANES; plane++) *ptr[plane] = 0; } /* Loop over colorants within a scan line. Remember that the order within a pixel is YMCK. */ for (colorant = BLACK_INDEX; colorant >= 0; colorant--) { from = line->str + pixel*OCTETS_PER_PIXEL + colorant; /* Determine approximation and error for this pixel */ approx = *from >> 7; error = *from - 255*approx; /* The sign of 'error' is chosen such that 'error' is positive if colorant intensity has to be added to the picture. */ /* Insert the approximation in the bit plane */ plane = BLACK_INDEX - colorant; *ptr[plane] = (*ptr[plane] << 1) | approx; error_propagation_colour() } if (pixel_mod_8 == 7) for (plane = 0; plane < PLANES; plane++) ptr[plane]++; } eprn_finalize(false, 2, PLANES, bitplanes, ptr, pixels); return;}/****************************************************************************** Function: split_colour_at_most_2() Floyd-Steinberg error diffusion for the non-monochrome process colour models using 2 intensity levels for the CMY colorants and at most 2 for the black colorant.******************************************************************************/static void split_colour_at_most_2(eprn_OctetString *line, eprn_OctetString *next_line, int max_octets, eprn_ColourModel colour_model, eprn_OctetString bitplanes[]){ const int last_colorant = colour_model == eprn_DeviceCMY_plus_K || colour_model == eprn_DeviceCMYK? BLACK_INDEX: 2, max_pixel = max_octets/OCTETS_PER_PIXEL - 1, planes = colour_model == eprn_DeviceCMY_plus_K || colour_model == eprn_DeviceCMYK? 4: 3; int colorant, correction, error, new_value, pixel, pixel_mod_8, pixels = line->length/OCTETS_PER_PIXEL, plane, remaining_error; eprn_Octet approx[4], *from, *ptr[4], *to; for (plane = 0; plane < planes; plane++) ptr[plane] = bitplanes[plane].str; /* Loop over pixels in the scan line. Note that 'pixels' may increase within the loop. */ for (pixel = 0, pixel_mod_8 = 8; pixel < pixels; pixel++, pixel_mod_8++) { if (pixel_mod_8 == 8) { pixel_mod_8 = 0; for (plane = 0; plane < planes; plane++) *ptr[plane] = 0; } /* Loop over colorants within a scan line. Remember that the order within a pixel is YMCK or BGR-. */ for (colorant = last_colorant; colorant >= 0; colorant--) { from = line->str + pixel*OCTETS_PER_PIXEL + colorant; /* Determine approximation and error for this pixel */ approx[colorant] = *from >> 7; error = *from - 255*approx[colorant]; /* The sign of 'error' is chosen such that 'error' is positive if colorant intensity has to be added to the picture. */ error_propagation_colour() } /* Determine the black component for CMY+K */ if (colour_model == eprn_DeviceCMY_plus_K && approx[0] == approx[1] && approx[1] == approx[2] && approx[0] > 0) { approx[BLACK_INDEX] = approx[0]; approx[0] = approx[1] = approx[2] = 0; } /* Distribute the approximation over the bit planes */ for (colorant = last_colorant, plane = 0; colorant >= 0; colorant--, plane++) { *ptr[plane] = (*ptr[plane] << 1) | approx[colorant]; } if (pixel_mod_8 == 7) for (plane = 0; plane < planes; plane++) ptr[plane]++; } eprn_finalize(colour_model == eprn_DeviceRGB, 2, planes, bitplanes, ptr, pixels); return;}/****************************************************************************** Function: split_colour() Floyd-Steinberg error diffusion for the non-monochrome process colour models and an arbitrary number of intensity levels.******************************************************************************/static void split_colour(eprn_OctetString *line, eprn_OctetString *next_line, int max_octets, eprn_ColourModel colour_model, unsigned int black_levels, unsigned int non_black_levels, eprn_OctetString bitplanes[]){ const int black_planes = eprn_bits_for_levels(black_levels), last_colorant = black_levels > 0? BLACK_INDEX: 2, max_pixel = max_octets/OCTETS_PER_PIXEL - 1, non_black_planes = eprn_bits_for_levels(non_black_levels), planes = black_planes + 3*non_black_planes; int colorant, correction, error, new_value, next_plane[4], pixel, pixel_mod_8, pixels = line->length/OCTETS_PER_PIXEL, plane, remaining_error; eprn_Octet approx[4], *from, *ptr[32], *to; unsigned int divisor[4], max_level[4]; if (black_levels > 0) { divisor[BLACK_INDEX] = 256/black_levels; max_level[BLACK_INDEX] = black_levels - 1; } else { divisor[BLACK_INDEX] = 0; max_level[BLACK_INDEX] = 0; } next_plane[BLACK_INDEX] = black_planes; for (colorant = 0; colorant < BLACK_INDEX; colorant++) { divisor[colorant] = 256/non_black_levels; max_level[colorant] = non_black_levels - 1; next_plane[colorant] = (3 - colorant)*non_black_planes + black_planes; } for (plane = 0; plane < planes; plane++) ptr[plane] = bitplanes[plane].str; /* Loop over pixels in the scan line. Note that 'pixels' may increase within the loop. */ for (pixel = 0, pixel_mod_8 = 8; pixel < pixels; pixel++, pixel_mod_8++) { if (pixel_mod_8 == 8) { pixel_mod_8 = 0; for (plane = 0; plane < planes; plane++) *ptr[plane] = 0; } /* Loop over colorants within a scan line */ for (colorant = last_colorant; colorant >= 0; colorant--) { from = line->str + pixel*OCTETS_PER_PIXEL + colorant; /* Determine approximation and error for this pixel */ approx[colorant] = *from/divisor[colorant]; error = *from - (255*approx[colorant])/max_level[colorant]; /* The sign of 'error' is chosen such that 'error' is positive if colorant intensity has to be added to the picture. */ error_propagation_colour() } /* Determine the black component for CMY+K */ if (colour_model == eprn_DeviceCMY_plus_K && approx[0] == approx[1] && approx[1] == approx[2] && approx[0] > 0) { int value = approx[0]*(black_levels - 1); if (value % (non_black_levels - 1) == 0) { /* Black does have a level at the same intensity as the CMY levels */ approx[BLACK_INDEX] = value/(non_black_levels - 1); approx[0] = approx[1] = approx[2] = 0; } } /* Distribute the approximation over the bit planes */ plane = 0; for (colorant = last_colorant; colorant >= 0; colorant--) { while (plane < next_plane[colorant]) { *ptr[plane] = (*ptr[plane] << 1) | approx[colorant] & 0x01; approx[colorant] >>= 1; plane++; } } if (pixel_mod_8 == 7) { int j; for (j = 0; j < planes; j++) ptr[j]++; } } eprn_finalize(colour_model == eprn_DeviceRGB, non_black_levels, planes, bitplanes, ptr, pixels); return;}/****************************************************************************** Function: eprn_split_FS This function performs Floyd-Steinberg error diffusion on a scan line and returns the result as bitplanes. 'line' points to the scan line to be split, 'next_line' to the following one. Both lines will be modified by this process. This modification assumes that the function is called successively for all lines, starting with the first. All octets up to 'max_octets' must be available in the input lines and, as far as they have not been included in the length fields, must be zero. The parameter 'colour_model' specifies the process colour model used. 'black_levels' is the number of intensity levels for the black colorant, 'non_black_levels' the corresponding number for the other colorants. 'bitplanes' is an array of bitplanes into which the result will be stored in the usual format.******************************************************************************/void eprn_split_FS(eprn_OctetString *line, eprn_OctetString *next_line, int max_octets, eprn_ColourModel colour_model, unsigned int black_levels, unsigned int non_black_levels, eprn_OctetString bitplanes[]){ if (colour_model == eprn_DeviceGray) { if (black_levels == 2) split_Gray_2(line, next_line, max_octets, bitplanes); else split_Gray(line, next_line, max_octets, black_levels, bitplanes); } else if (colour_model == eprn_DeviceCMYK && black_levels == 2 && non_black_levels == 2) split_colour_CMYK_2(line, next_line, max_octets, bitplanes); else { if (black_levels <= 2 && non_black_levels == 2) split_colour_at_most_2(line, next_line, max_octets, colour_model, bitplanes); else split_colour(line, next_line, max_octets, colour_model, black_levels, non_black_levels, bitplanes); } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -