0

refac: PcxFile

This commit is contained in:
2026-02-12 00:54:58 +03:00
parent b9d31e6fbe
commit 9cad290a68
4 changed files with 110 additions and 80 deletions

View File

@@ -27,11 +27,11 @@ import lwjake2.qcommon.Cvar;
import lwjake2.qcommon.FS; import lwjake2.qcommon.FS;
import lwjake2.qcommon.MSG; import lwjake2.qcommon.MSG;
import lwjake2.qcommon.SZ; import lwjake2.qcommon.SZ;
import lwjake2.qcommon.qfiles;
import lwjake2.sound.S; import lwjake2.sound.S;
import lwjake2.sys.Timer; import lwjake2.sys.Timer;
import lwjake2.util.Lib; import lwjake2.util.Lib;
import lwjake2.util.Vargs; import lwjake2.util.Vargs;
import ru.di9.lwjake2.PcxFile;
import java.awt.Dimension; import java.awt.Dimension;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@@ -1366,7 +1366,7 @@ public final class SCR extends Globals {
* LoadPCX * LoadPCX
*/ */
static int LoadPCX(String filename, byte[] palette, cinematics_t cin) { static int LoadPCX(String filename, byte[] palette, cinematics_t cin) {
qfiles.pcx_t pcx; PcxFile pcx;
// load the file // load the file
ByteBuffer raw = FS.LoadMappedFile(filename); ByteBuffer raw = FS.LoadMappedFile(filename);
@@ -1378,18 +1378,18 @@ public final class SCR extends Globals {
} }
// parse the PCX file // parse the PCX file
pcx = new qfiles.pcx_t(raw); pcx = new PcxFile(raw);
if (pcx.manufacturer != 0x0a || pcx.version != 5 || pcx.encoding != 1 if (pcx.getManufacturer() != 0x0a || pcx.getVersion() != 5 || pcx.getEncoding() != 1
|| pcx.bits_per_pixel != 8 || pcx.xmax >= 640 || pcx.getBitsPerPixel() != 8 || pcx.getXmax() >= 640
|| pcx.ymax >= 480) { || pcx.getYmax() >= 480) {
VID.Printf(Defines.PRINT_ALL, "Bad pcx file " + filename + '\n'); VID.Printf(Defines.PRINT_ALL, "Bad pcx file " + filename + '\n');
return 0; return 0;
} }
int width = pcx.xmax - pcx.xmin + 1; int width = pcx.getXmax() - pcx.getXmin() + 1;
int height = pcx.ymax - pcx.ymin + 1; int height = pcx.getYmax() - pcx.getYmin() + 1;
byte[] pix = new byte[width * height]; byte[] pix = new byte[width * height];
@@ -1418,11 +1418,11 @@ public final class SCR extends Globals {
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
for (x = 0; x < width;) { for (x = 0; x < width;) {
dataByte = pcx.data.get(p++); dataByte = pcx.getData().get(p++);
if ((dataByte & 0xC0) == 0xC0) { if ((dataByte & 0xC0) == 0xC0) {
runLength = dataByte & 0x3F; runLength = dataByte & 0x3F;
dataByte = pcx.data.get(p++); dataByte = pcx.getData().get(p++);
// write runLength pixel // write runLength pixel
while (runLength-- > 0) { while (runLength-- > 0) {
pix[count++] = dataByte; pix[count++] = dataByte;

View File

@@ -47,64 +47,6 @@ public class qfiles {
/* /*
======================================================================== ========================================================================
PCX files are used for as many images as possible
========================================================================
*/
public static class pcx_t {
// size of byte arrays
static final int PALETTE_SIZE = 48;
static final int FILLER_SIZE = 58;
public byte manufacturer;
public byte version;
public byte encoding;
public byte bits_per_pixel;
public int xmin, ymin, xmax, ymax; // unsigned short
public int hres, vres; // unsigned short
public byte[] palette; //unsigned byte; size 48
public byte reserved;
public byte color_planes;
public int bytes_per_line; // unsigned short
public int palette_type; // unsigned short
public byte[] filler; // size 58
public ByteBuffer data; //unbounded data
public pcx_t(byte[] dataBytes) {
this(ByteBuffer.wrap(dataBytes));
}
public pcx_t(ByteBuffer b) {
// is stored as little endian
b.order(ByteOrder.LITTLE_ENDIAN);
// fill header
manufacturer = b.get();
version = b.get();
encoding = b.get();
bits_per_pixel = b.get();
xmin = b.getShort() & 0xffff;
ymin = b.getShort() & 0xffff;
xmax = b.getShort() & 0xffff;
ymax = b.getShort() & 0xffff;
hres = b.getShort() & 0xffff;
vres = b.getShort() & 0xffff;
b.get(palette = new byte[PALETTE_SIZE]);
reserved = b.get();
color_planes = b.get();
bytes_per_line = b.getShort() & 0xffff;
palette_type = b.getShort() & 0xffff;
b.get(filler = new byte[FILLER_SIZE]);
// fill data
data = b.slice();
}
}
/*
========================================================================
TGA files are used for sky planes TGA files are used for sky planes
======================================================================== ========================================================================

View File

@@ -44,6 +44,7 @@ import org.lwjgl.opengl.ARBImaging;
import org.lwjgl.opengl.ARBMultitexture; import org.lwjgl.opengl.ARBMultitexture;
import org.lwjgl.opengl.EXTSharedTexturePalette; import org.lwjgl.opengl.EXTSharedTexturePalette;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import ru.di9.lwjake2.PcxFile;
/** /**
* Image * Image
@@ -445,7 +446,7 @@ public abstract class Image extends Main {
============== ==============
*/ */
byte[] LoadPCX(String filename, byte[][] palette, Dimension dim) { byte[] LoadPCX(String filename, byte[][] palette, Dimension dim) {
qfiles.pcx_t pcx; PcxFile pcx;
// //
// load the file // load the file
@@ -460,21 +461,21 @@ public abstract class Image extends Main {
// //
// parse the PCX file // parse the PCX file
// //
pcx = new qfiles.pcx_t(raw); pcx = new PcxFile(ByteBuffer.wrap(raw));
if (pcx.manufacturer != 0x0a if (pcx.getManufacturer() != 0x0a
|| pcx.version != 5 || pcx.getVersion() != 5
|| pcx.encoding != 1 || pcx.getEncoding() != 1
|| pcx.bits_per_pixel != 8 || pcx.getBitsPerPixel() != 8
|| pcx.xmax >= 640 || pcx.getXmax() >= 640
|| pcx.ymax >= 480) { || pcx.getYmax() >= 480) {
VID.Printf(Defines.PRINT_ALL, "Bad pcx file " + filename + '\n'); VID.Printf(Defines.PRINT_ALL, "Bad pcx file " + filename + '\n');
return null; return null;
} }
int width = pcx.xmax - pcx.xmin + 1; int width = pcx.getXmax() - pcx.getXmin() + 1;
int height = pcx.ymax - pcx.ymin + 1; int height = pcx.getYmax() - pcx.getYmin() + 1;
byte[] pix = new byte[width * height]; byte[] pix = new byte[width * height];
@@ -499,11 +500,11 @@ public abstract class Image extends Main {
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
for (x = 0; x < width;) { for (x = 0; x < width;) {
dataByte = pcx.data.get(); dataByte = pcx.getData().get();
if ((dataByte & 0xC0) == 0xC0) { if ((dataByte & 0xC0) == 0xC0) {
runLength = dataByte & 0x3F; runLength = dataByte & 0x3F;
dataByte = pcx.data.get(); dataByte = pcx.getData().get();
// write runLength pixel // write runLength pixel
while (runLength-- > 0) { while (runLength-- > 0) {
pix[count++] = dataByte; pix[count++] = dataByte;

View File

@@ -0,0 +1,87 @@
package ru.di9.lwjake2;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class PcxFile {
private static final int PALETTE_SIZE = 48;
private static final int FILLER_SIZE = 58;
private final byte manufacturer;
private final byte version;
private final byte encoding;
private final byte bits_per_pixel;
private final int xmin; // unsigned short
private final int xmax; // unsigned short
private final int ymax; // unsigned short
private final int ymin; // unsigned short
private final ByteBuffer data; //unbounded data
public PcxFile(ByteBuffer buffer) {
// is stored as little endian
buffer.order(ByteOrder.LITTLE_ENDIAN);
// fill header
manufacturer = buffer.get();
version = buffer.get();
encoding = buffer.get();
bits_per_pixel = buffer.get();
xmin = buffer.getShort() & 0xffff;
ymin = buffer.getShort() & 0xffff;
xmax = buffer.getShort() & 0xffff;
ymax = buffer.getShort() & 0xffff;
// Skip bytes
buffer.position(buffer.position()
+ 2 // unsigned short 'hres'
+ 2 // unsigned short 'vres'
+ PALETTE_SIZE // array unsigned bytes 'palette'
+ 1 // byte 'reserved'
+ 1 // byte 'color_planes'
+ 2 // unsigned short 'bytes_per_line'
+ 2 // unsigned short 'palette_type'
+ FILLER_SIZE // array unsigned bytes 'filler'
);
// fill data
data = buffer.slice();
}
public byte getManufacturer() {
return manufacturer;
}
public byte getVersion() {
return version;
}
public byte getEncoding() {
return encoding;
}
public byte getBitsPerPixel() {
return bits_per_pixel;
}
public int getXmax() {
return xmax;
}
public int getYmax() {
return ymax;
}
public int getXmin() {
return xmin;
}
public int getYmin() {
return ymin;
}
public ByteBuffer getData() {
return data;
}
}