Tu não entendeste bem minha questão.
O sistema é uma vm. E quando a aplicação envia a imagem para ser impressa, a vm desmembra a imagem, remove o header, separa os dados da imagem. Depois, tem que remontar o cabeçalho e imprimir. Qualquer formato de imagem pode ser enviado. Entretanto, o dispositivo só aceita imagens no formato bmp. Como bem sabemos, o formato bitmap tem suas informações invertidas. O algoritmo do sistema os corrige invertendo os dados da imagem. Entretanto, o firmware do dispositivo quer um bmp autêntico, e não um que foi alterado. Então eu tenho que inverter a imagem para que ela seja impressa de forma correta.
Me foi apresentada essa solução logo abaixo, entretanto, não entendi que regra que foi aplicada para a inversão da imagem, não encontrei material que ensine.
void PrinterImage(WNMEnv *env, Var stack[])
{
//OSL_Debug("TESTE IMPRESSORA - nmt4waba.c - PrinterImage");
uint32 bitmapOffset;
WObject objImg = stack[0].obj;
unsigned int width = WOBJ_ImageWidth(env, objImg);
unsigned int height = WOBJ_ImageHeight(env, objImg);
uint16 bpp = WOBJ_ImageBPP(env, objImg);
if (bpp>1)
env->ThrowException(env, InputOutputException, "bpp deve ser 1");
WObject objRGBArray = WOBJ_ImageRGB(env, objImg);
uchar *rgb = (uchar *)WOBJ_arrayStart(env, objRGBArray);//recebendo dados da imagem
//AQUI NÃO ENTENDI ESSA LÓGICA MALUCA, MAS FUNCIONA - NÃO ENCONTREI MATERIAL QUE EXPLIQUE TAL REGRA
unsigned int bytesPerRow = (width >> 3) + (width & 0x7 ? 1 : 0);
int rgbLen = WOBJ_arrayLen(env, objRGBArray);//tamanho dos dados da imagem
struct BMPColorTable bmpFormat; //Estrutura bmp a ser montada
memset(&bmpFormat, 0, sizeof(bmpFormat));
bitmapOffset= sizeof(bmpFormat); //tamanho da estrutura bmp
unsigned int fileSize= bitmapOffset+ rgbLen;//tamanho total da imagem
//--------------------------------- BMP FILE FORMAT -----------------------------------
//***** File Header ***********
bmpFormat.header.signature = (0x4D << 8) | 0x42; // 0-1 magic chars 'BM' uint16
bmpFormat.header.fileSize = fileSize; // 2-5 uint32 filesize (not reliable) tamanho total em bytes da imagem
bmpFormat.header.filler1 = 0; // 6-9 uint32 0
bmpFormat.header.bitmapOffset = bitmapOffset; // 10-13 uint32 bitmapOffset é a posição onde iniciam os dados
//******************************
//***** Image Header ***********
bmpFormat.header.infoSize = 40; // 14-17 uint32 info size - Tamanho de Image Header
bmpFormat.header.width = width; // 18-21 int32 width tamanho maximo: 384
bmpFormat.header.height = height; // 22-25 int32 height tamanho maximo: 128
bmpFormat.header.nPlanes = 1; // 26-27 uint16 nplanes - sempre sera igual 1
bmpFormat.header.bpp = bpp; // 28-29 uint16 bits per pixel - aqui o bpp deve ser 1, do contrario ocorrerá um exception
bmpFormat.header.compression = 0; // 30-33 uint32 compression flag
bmpFormat.header.imageSize =0; // 34-37 uint32 image size (compressed) in bytes - aqui fica zero se compressão for zero
bmpFormat.header.biXPelsPerMeter = 0; // 38-41 int32 biXPelsPerMeter - valores que servem para ajustar a imagem ao tamanho da tela do dispositivo
bmpFormat.header.biYPelsPerMeter = 0; // 32-45 int32 biYPelsPerMeter - valores que servem para ajustar a imagem ao tamanho da tela do dispositivo
bmpFormat.header.colorsUsed = 0; // 46-49 uint32 colors used
bmpFormat.header.importantColorCount = 0; // 50-53 uint32 important color count
//******************************
//***** Color Table ************
bmpFormat.color1= 0; // 54-57 uint32 color cor preta
bmpFormat.color2= 0x00FFFFFF; // 58-61 uint32 color cor branca
//*******************************
//---------------------------------------------------------------------------------------
uchar *bitmapStream = (uchar *)wabaVm->MemAlloc(fileSize);
memset(bitmapStream,0,fileSize);
memcpy(bitmapStream, &bmpFormat, sizeof(bmpFormat)); //copiando a estrutura bmp para montar a imagem
//Inverte os dados da imagem e armazena-os, finalizando toda a estrutura da imagem
int row;
for (row = height - 1; row >= 0; row--)
memcpy(&(bitmapStream[bitmapOffset + row * bytesPerRow]), &rgb[(height - row - 1) * bytesPerRow], bytesPerRow);
//Imprime imagem
PrintWithGoal(bitmapStream,fileSize,1);
wabaVm->MemFree(bitmapStream);
}