PDT文件格式分析

2024-02-24 02:08
文章标签 分析 文件格式 pdt

本文主要是介绍PDT文件格式分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

PDT也是PC98中经常出现的图片格式。现已发现的有MEBIUS和BonBeeBon等公司使用此格式。代表游戏有《YORO》《恶梦-青色果实》《SHAKESHAKE2》等。

此格式在早期相当简单、但随着压缩要求日益增加的后期,被扩充得相当复杂。截至目前为止仍有一些为知的图片不能被解码。

首字节为子格式代码,现在已知的有FF,31,32,33,34,38等。其中34H和38H号有自带调色板数据。

38号格式使用LZ77编码的一个变种,一个1920长度的窗口作为字典来压缩。

34号格式使用流程码压缩。其文件开头在34H字节之后的两个字节指出两个特殊编码作为流程码起始标志。特殊码1表示重复给出的字(WORD)n次。特殊码2表示对下面两个字节的转义。此格式压缩效率不高,类似PCX格式,但实际出现的概率相当高,实践证明,对子格式不详的文件也可尝试先用此格式解码。

FF号格式比34号格式压缩效率更低,所有的编码都必须以2字节前缀打头。但流程码长可以达到最长256字节,非常适合编码单色或者是文本形式的图片。

32号格式目前尚未发现实际的图片。

33号格式是38号格式无调色板的版本。

 

注:没有带调色板的图片直接解码图片的颜色是不对的。这时,请寻找游戏中的COLOR.TBL文件。并以-p color.tbl n (n>=0)格式指出外部调色板并确认解码结果。通常n取2-4。

因为尚未完全知晓所有子格式,若解码中途出错,可删除出错的PDT文件继续。

 

以下为代码,使用方法为:(例)pdt *.pdt或pdt *.pdt -p color.tbl 2

在VS2003上编译通过。

 

// pdt.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#pragma warning(disable: 4996)
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <io.h>

typedef struct __tag_pdt_rec_t {
 unsigned char* src_buf;
 int    src_buf_size;
 unsigned short palette[16];
 int    has_palette;
} pdt_rec_t;

void pdt_init(pdt_rec_t* rec)
{
 rec->src_buf = NULL;
 rec->src_buf_size = 0;
 rec->has_palette = 0;
}

void pdt_free(pdt_rec_t* rec)
{
 if (rec->src_buf) {
  free(rec->src_buf);
  rec->src_buf = NULL;
 }
}

int pdt_load(pdt_rec_t* rec, const char* filename)
{
 FILE* fp = fopen(filename, "rb");
 fseek(fp, 0, SEEK_END);
 rec->src_buf_size = (int)ftell(fp);
 fseek(fp, 0, SEEK_SET);
 rec->src_buf = (unsigned char*)malloc(rec->src_buf_size);
 if (rec->src_buf) {
  fread(rec->src_buf, rec->src_buf_size, 1, fp);
 }
 fclose(fp);
 return rec->src_buf != NULL;
}

#define READ_WORD(p) *(unsigned short*)(p)

int pdt_decode31(pdt_rec_t* rec, const char* target_file)
{
 const unsigned char* p = rec->src_buf;
 unsigned short palette_data[16] = { 0x000, 0x222, 0x444, 0x666, 0x888, 0xAAA, 0xCCC, 0xFFF,
  0x8B9, 0xADB, 0x64C, 0x89F, 0x79F, 0x9BF, 0xBDF, 0xFFF };
 ++p;
 unsigned short left = 0;
 unsigned short top = 0;
 unsigned short right = 0;
 unsigned short bottom = 0;
 left = READ_WORD(p);
 p += 2;
 top = READ_WORD(p);
 p += 2;
 right = READ_WORD(p);
 p += 2;
 bottom = READ_WORD(p);
 p += 2;

 unsigned short width = right - left + 1;
 unsigned short height = bottom - top + 1;
 int bpl = width;
 /// bytes per plane
 int bpp = bpl*height;
 unsigned char* work_buf = (unsigned char*)malloc((int)bpp*4);
 unsigned char* dest = NULL;
 unsigned char dh;
 unsigned short i, n;
 int plane_order[4] = { 3, 0, 1, 2 };
 for ( int plane = 0; plane < 4; ++plane ) {
  unsigned short x = 0;
  unsigned short y = 0;
  while (x < width) {
   unsigned char al = *p++;
   unsigned char ah = *p++;
   dest = work_buf + bpp*plane_order[plane] + x + bpl * y;
   if (ah == al) {
    /// Repeat mode
    dh = al;
    al = *p++;
    ah = *p++;
    n = ah;
    ++n;
    for ( i = 0; i < n; ++i ) {
     *dest = dh;
     dest+=bpl;
     *dest = al;
     dest+=bpl;
     y+=2;
     if (y >= height) {
      y = 0;
      ++x;
      dest = work_buf + bpp*plane_order[plane] + x + bpl * y;
     }
    }
   } else {
    /// Single mode
    *dest = al;
    dest+=bpl;
    *dest = ah;
    dest+=bpl;
    y+=2;
    if (y >= height) {
     y = 0;
     ++x;
     dest = work_buf + bpp*plane_order[plane] + x + bpl * y;
    }
   }
  }
 }

 unsigned char ch0, ch1, ch2, ch3;
 unsigned char *bits_buffer = (unsigned char*)malloc(bpl*4*height);
 memset(bits_buffer, 0, bpl*4*height);
 int line_words = bpl/2;
 unsigned char* src = work_buf;
 dest = bits_buffer;
 for ( int y = 0; y < height; ++y ) {
  for ( int x = 0; x < width; ++x ) {
   ch0 = *(work_buf + bpp*0 + x + bpl * (height-1-y));
   ch1 = *(work_buf + bpp*1 + x + bpl * (height-1-y));
   ch2 = *(work_buf + bpp*2 + x + bpl * (height-1-y));
   ch3 = *(work_buf + bpp*3 + x + bpl * (height-1-y));

   if (ch0 & 0x80) dest[0] |= 0x10;
   if (ch1 & 0x80) dest[0] |= 0x20;
   if (ch2 & 0x80) dest[0] |= 0x40;
   if (ch3 & 0x80) dest[0] |= 0x80;

   if (ch0 & 0x40) dest[0] |= 0x01;
   if (ch1 & 0x40) dest[0] |= 0x02;
   if (ch2 & 0x40) dest[0] |= 0x04;
   if (ch3 & 0x40) dest[0] |= 0x08;

   if (ch0 & 0x20) dest[1] |= 0x10;
   if (ch1 & 0x20) dest[1] |= 0x20;
   if (ch2 & 0x20) dest[1] |= 0x40;
   if (ch3 & 0x20) dest[1] |= 0x80;

   if (ch0 & 0x10) dest[1] |= 0x01;
   if (ch1 & 0x10) dest[1] |= 0x02;
   if (ch2 & 0x10) dest[1] |= 0x04;
   if (ch3 & 0x10) dest[1] |= 0x08;

   if (ch0 & 0x08) dest[2] |= 0x10;
   if (ch1 & 0x08) dest[2] |= 0x20;
   if (ch2 & 0x08) dest[2] |= 0x40;
   if (ch3 & 0x08) dest[2] |= 0x80;

   if (ch0 & 0x04) dest[2] |= 0x01;
   if (ch1 & 0x04) dest[2] |= 0x02;
   if (ch2 & 0x04) dest[2] |= 0x04;
   if (ch3 & 0x04) dest[2] |= 0x08;

   if (ch0 & 0x02) dest[3] |= 0x10;
   if (ch1 & 0x02) dest[3] |= 0x20;
   if (ch2 & 0x02) dest[3] |= 0x40;
   if (ch3 & 0x02) dest[3] |= 0x80;

   if (ch0 & 0x01) dest[3] |= 0x01;
   if (ch1 & 0x01) dest[3] |= 0x02;
   if (ch2 & 0x01) dest[3] |= 0x04;
   if (ch3 & 0x01) dest[3] |= 0x08;

   dest += 4;
  }
 }

 BITMAPFILEHEADER bfh;
 BITMAPINFOHEADER bmi;
 memset(&bfh, 0, sizeof(BITMAPFILEHEADER));
 bfh.bfType = 'MB';
 bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
 bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 64;
 memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
 bmi.biSize = sizeof(BITMAPINFOHEADER);
 bmi.biSizeImage = bpp * 4;
 bmi.biWidth = width * 8;
 bmi.biHeight = height;
 bmi.biPlanes = 1;
 bmi.biBitCount = 4;
 bmi.biClrUsed = 16;
 bmi.biClrImportant = 16;
 FILE *fp = fopen(target_file, "wb");
 fwrite(&bfh, 1, sizeof bfh, fp);
 fwrite(&bmi, 1, sizeof bmi, fp);
 unsigned char palette[64];
 for ( int i = 0; i < 16; ++i ) {
  palette[i*4+1] = ((palette_data[i]>>8) << 4) + 0xF;
  palette[i*4+2] = (((palette_data[i]>>4)&0xF)<<4) + 0xF;
  palette[i*4+0] = ((palette_data[i]&0xF)<<4) + 0xF;
  palette[i*4+3] = 0;
 }
 fwrite(palette, 4, 16, fp);
 fwrite(bits_buffer, 1, bpp*4, fp);
 fclose(fp);

 free(work_buf);
 free(bits_buffer);

 return 1;
}

int pdt_decodeFF(pdt_rec_t* rec, const char* target_file)
{
 /// TODO
 return 0;
}

int pdt_decode34(pdt_rec_t* rec, const char* target_file)
{
 const unsigned char* p = rec->src_buf;
 unsigned char has_palette = 1;
 if (*p != 0x34) {
  if (*p == 0x31) {
   /// BON.PDT?
   return pdt_decode31(rec, target_file);
  }
  if (*p == 0xFF) {
   return pdt_decodeFF(rec, target_file);
  }
  has_palette = 0;
  ///if (*p == 0x33) has_palette = 1;
  /// TODO: 2nd = 3rd == 00....  FF
  //printf("No palette, ignored/n");
  //return 0;
 }
 ++p;
 unsigned char const_2nd_byte = *p++;
 unsigned char const_3rd_byte = *p++;

 unsigned short left = 0;
 unsigned short top = 0;
 unsigned short right = 0;
 unsigned short bottom = 0;
 left = READ_WORD(p);
 p += 2;
 top = READ_WORD(p);
 p += 2;
 right = READ_WORD(p);
 p += 2;
 bottom = READ_WORD(p);
 p += 2;

 unsigned short width = right-left+1;
 unsigned short scan_lines = (bottom-top)/2+1;
 unsigned short height = scan_lines*2;

 unsigned short palette_data[16] = { 0x000, 0x222, 0x444, 0x666, 0x888, 0xAAA, 0xCCC, 0xFFF,
  0x8B9, 0xADB, 0x64C, 0x89F, 0x79F, 0x9BF, 0xBDF, 0xFFF };
 if (has_palette) {
  memcpy(palette_data, p, 32);
  p += 32;
 }
 if (rec->has_palette) {
  memcpy(palette_data, rec->palette, 32);
 }
 int bytes_per_line = width << 2;

 unsigned char* work_buf = (unsigned char*)malloc((int)bytes_per_line*height);
 memset(work_buf, 0, (int)bytes_per_line*height);
 int bytes_per_plane = width*height;
 unsigned char* dest = work_buf;

 for ( int plane = 0; plane < 4; ++plane ) {
  for ( int x = 0; x < width; ++x ) {
   dest = work_buf + plane*bytes_per_plane + x;
   int y = 0;
   while ( y < scan_lines ) {
    unsigned char ah = 0, al = 0, cl = 0;
    if (*p == const_2nd_byte) {
     ++p;
     al = *p++;
     ah = *p++;
     cl = *p++;
    } else if (*p == const_3rd_byte) {
     ++p;
     al = *p++;
     ah = al;
     cl = *p++;
    } else {
     al = *p++;
     ah = *p++;
     cl = 1;
    }
    y += cl;
    do {
     *dest = al;
     dest += width;
     *dest = ah;
     dest += width;
    } while (--cl != 0);
   }
  }
 }

 // 4 planes -> b4b4
 // a0 a1 a2 a3 a4 a5 a6 a7
 // b0 b1 b2 b3 b4 b5 b6 b7
 // c0 c1 c2 c3 c4 c5 c6 c7
 // d0 d1 d2 d3 d4 d5 d6 d7
 // ==>
 // a0b0c0d0 a1b1c1d1 ; a2b2c2d2 a3b3c3d3 ; a4b4c4d4 a5b5c5d5 ; a6b6c6d6 a7b7c7d7
 int bpl = width;
 unsigned char ch0, ch1, ch2, ch3;
 unsigned char *bits_buffer = (unsigned char*)malloc(bpl*4*height);
 memset(bits_buffer, 0, bpl*4*height);
 int line_words = bpl/2;
 int i = 0;
 unsigned char* src = work_buf;
 dest = bits_buffer;
 for ( int y = 0; y < height; ++y ) {
  for ( int x = 0; x < width; ++x ) {
   ch0 = *(work_buf + bytes_per_plane*0 + x + bpl * (height-1-y));
   ch1 = *(work_buf + bytes_per_plane*1 + x + bpl * (height-1-y));
   ch2 = *(work_buf + bytes_per_plane*2 + x + bpl * (height-1-y));
   ch3 = *(work_buf + bytes_per_plane*3 + x + bpl * (height-1-y));

   if (ch0 & 0x80) dest[0] |= 0x10;
   if (ch1 & 0x80) dest[0] |= 0x20;
   if (ch2 & 0x80) dest[0] |= 0x40;
   if (ch3 & 0x80) dest[0] |= 0x80;

   if (ch0 & 0x40) dest[0] |= 0x01;
   if (ch1 & 0x40) dest[0] |= 0x02;
   if (ch2 & 0x40) dest[0] |= 0x04;
   if (ch3 & 0x40) dest[0] |= 0x08;

   if (ch0 & 0x20) dest[1] |= 0x10;
   if (ch1 & 0x20) dest[1] |= 0x20;
   if (ch2 & 0x20) dest[1] |= 0x40;
   if (ch3 & 0x20) dest[1] |= 0x80;

   if (ch0 & 0x10) dest[1] |= 0x01;
   if (ch1 & 0x10) dest[1] |= 0x02;
   if (ch2 & 0x10) dest[1] |= 0x04;
   if (ch3 & 0x10) dest[1] |= 0x08;

   if (ch0 & 0x08) dest[2] |= 0x10;
   if (ch1 & 0x08) dest[2] |= 0x20;
   if (ch2 & 0x08) dest[2] |= 0x40;
   if (ch3 & 0x08) dest[2] |= 0x80;

   if (ch0 & 0x04) dest[2] |= 0x01;
   if (ch1 & 0x04) dest[2] |= 0x02;
   if (ch2 & 0x04) dest[2] |= 0x04;
   if (ch3 & 0x04) dest[2] |= 0x08;

   if (ch0 & 0x02) dest[3] |= 0x10;
   if (ch1 & 0x02) dest[3] |= 0x20;
   if (ch2 & 0x02) dest[3] |= 0x40;
   if (ch3 & 0x02) dest[3] |= 0x80;

   if (ch0 & 0x01) dest[3] |= 0x01;
   if (ch1 & 0x01) dest[3] |= 0x02;
   if (ch2 & 0x01) dest[3] |= 0x04;
   if (ch3 & 0x01) dest[3] |= 0x08;

   dest += 4;
  }
 }

 BITMAPFILEHEADER bfh;
 BITMAPINFOHEADER bmi;
 memset(&bfh, 0, sizeof(BITMAPFILEHEADER));
 bfh.bfType = 'MB';
 bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
 bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 64;
 memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
 bmi.biSize = sizeof(BITMAPINFOHEADER);
 bmi.biSizeImage = bytes_per_line * height;
 bmi.biWidth = width * 8;
 bmi.biHeight = height;
 bmi.biPlanes = 1;
 bmi.biBitCount = 4;
 bmi.biClrUsed = 16;
 bmi.biClrImportant = 16;
 FILE *fp = fopen(target_file, "wb");
 fwrite(&bfh, 1, sizeof bfh, fp);
 fwrite(&bmi, 1, sizeof bmi, fp);
 unsigned char palette[64];
 for ( int i = 0; i < 16; ++i ) {
  palette[i*4+1] = ((palette_data[i]>>8) << 4) + 0xF;
  palette[i*4+2] = (((palette_data[i]>>4)&0xF)<<4) + 0xF;
  palette[i*4+0] = ((palette_data[i]&0xF)<<4) + 0xF;
  palette[i*4+3] = 0;
 }
 fwrite(palette, 4, 16, fp);
 fwrite(bits_buffer, 1, bytes_per_line * height, fp);
 fclose(fp);

 free(work_buf);
 free(bits_buffer);

 return 1;
}

int pdt_decode(pdt_rec_t* rec, const char* target_file)
{
#define READ_WORD(p) *(unsigned short*)(p)

 const unsigned char* p = rec->src_buf;
 if (*p != 0x38) {
  return pdt_decode34(rec, target_file);
//  printf("Error: unknown format: 0x%x", *p);
//  throw 1;
 }
 unsigned short left = 0;
 unsigned short top = 0;
 unsigned short right = 0;
 unsigned short bottom = 0;

 p += 3;
 left = READ_WORD(p);
 p += 2;
 top = READ_WORD(p);
 p += 2;
 right = READ_WORD(p);
 p += 2;
 bottom = READ_WORD(p);
 p += 2;
 ++bottom;

 unsigned short width = right-left;
 unsigned short height = bottom-top;
 int bpl = width << 4; /// bits per line width:80 640/2=320bytes bpl:80x16=1280 bytes=4 lines
 int bytes_per_line = width << 2;
 unsigned short palette_data[16];
 memcpy(palette_data, p, 32);
 p += 32;

 unsigned char line_buf[1920];
 memset(line_buf, 0, 1920); 
 unsigned short offset_table[16];
 memcpy(offset_table, p, 32);
 p += 32;
 unsigned char* addr_limit = line_buf + bytes_per_line + bpl;
 
 unsigned char left_bits = 0;
 unsigned char left_n = 0;
 unsigned short y = 0;
 unsigned char al = 0;
 
 unsigned char* bits_buffer = (unsigned char*)malloc((int)bytes_per_line*height);
 memset(bits_buffer, 0, (int)bytes_per_line*height);

 unsigned char* addr = line_buf + bpl;

 for ( y = 0; y < height; ++y ) {
  ///if (y == height-1) _asm int 3;

  
  while (addr < addr_limit) {
   al = *p++;
   if (left_n == 0) {
    left_n = 8;
    left_bits = al;
    al = *p++;
   }
   if (left_bits & 0x80) {
    /// dict
    unsigned char ch = al;
    unsigned short tbl_offset = offset_table[(ch >> 4) & 0xF];
    unsigned short cnt = (ch & 0xF) + 2;
    for ( int i = 0; i < cnt; ++i ) {
     if (addr-tbl_offset >= line_buf && addr-tbl_offset < &line_buf[1920]) {
      *addr = *(addr-tbl_offset);
     }
     ++addr;
    }
   } else {
    /// direct byte
    *addr++ = al;
   }
   left_bits<<=1;
   --left_n;
  }

  ///addr = line_buf + bpl;
  addr -= bytes_per_line;
  unsigned char ch = 0;
  unsigned char src = 0;
  unsigned char* bits_p = bits_buffer + (int)(height-y-1) * bytes_per_line;
  for ( int i = 0; i < bytes_per_line; ++i ) {
   ch = 0;
   src = line_buf[i+bpl];
   if (src & 0x80) ch |= 0x10;
   if (src & 0x40) ch |= 0x01;
   if (src & 0x20) ch |= 0x20;
   if (src & 0x10) ch |= 0x02;
   if (src & 0x08) ch |= 0x40;
   if (src & 0x04) ch |= 0x04;
   if (src & 0x02) ch |= 0x80;
   if (src & 0x01) ch |= 0x08; 
   *bits_p++ = ch;
  }
  //for ( int i = 0; i < bpl+bytes_per_line; ++i ) {
  // line_buf[i] = line_buf[i+bytes_per_line];
  //}
  memcpy(line_buf, line_buf+bytes_per_line, bpl+bytes_per_line);
 }

 BITMAPFILEHEADER bfh;
 BITMAPINFOHEADER bmi;
 memset(&bfh, 0, sizeof(BITMAPFILEHEADER));
 bfh.bfType = 'MB';
 bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
 bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 64;
 memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
 bmi.biSize = sizeof(BITMAPINFOHEADER);
 bmi.biSizeImage = bytes_per_line * height;
 bmi.biWidth = width * 8;
 bmi.biHeight = height;
 bmi.biPlanes = 1;
 bmi.biBitCount = 4;
 bmi.biClrUsed = 16;
 bmi.biClrImportant = 16;
 FILE *fp = fopen(target_file, "wb");
 fwrite(&bfh, 1, sizeof bfh, fp);
 fwrite(&bmi, 1, sizeof bmi, fp);
 unsigned char palette[64];
 for ( int i = 0; i < 16; ++i ) {
  palette[i*4+1] = ((palette_data[i]>>8) << 4) + 0xF;
  palette[i*4+2] = (((palette_data[i]>>4)&0xF)<<4) + 0xF;
  palette[i*4+0] = ((palette_data[i]&0xF)<<4) + 0xF;
  palette[i*4+3] = 0;
 }
 fwrite(palette, 4, 16, fp);
 fwrite(bits_buffer, 1, bytes_per_line * height, fp);
 fclose(fp);
 free(bits_buffer);
 return 1;
}

int help_text(void)
{
 printf("usage: pdt [pdt files(E.G: *.PDT)] [-p palette_file [index]]/n");
 printf("  E.G: pdt *.pdt -p color.tbl 1/n");
 return -1;
}

int _tmain(int argc, _TCHAR* argv[])
{
 pdt_rec_t rec;
 pdt_init(&rec);

 char *input_files = "*.PDT";
 char *pal_file = NULL;
 int pal_index = 0;
 int input_file_found = 0;
 for ( int i = 1; i < argc; ) {
  if (argv[i][0] == '-' || argv[i][0] == '/') {
   if (argv[i][1] == 'p' || argv[i][1] == 'P') {
    if (i + 1 < argc) {
     pal_file = argv[i+1];
     if ((i + 1 < argc && input_file_found) || i + 2 < argc) {
      pal_index = atoi(argv[i+2]);
      i+=3;
     } else {
      i+=2;
     }
    } else return help_text();
   } else if (argv[i][1] == 'h' || argv[i][1] == 'H' || argv[i][1] == '?') {
    return help_text();
   } else return help_text();
  } else {
   if (!input_file_found) {
    input_file_found = 1;
    input_files = argv[i];
    ++i;
   } else return help_text();
  }
 }
 if ( argc > 5 ) {
  return help_text();
 }
 if (pal_file) {
  FILE* fp = fopen(pal_file, "rb");
  if (!fp) {
   printf("Error: cannot load palette file: %s/n", pal_file);
  } else {
   fseek(fp, pal_index*32, SEEK_SET);
   fread(rec.palette, 1, 32, fp);
   rec.has_palette = 1;
   fclose(fp);
  }
 }
 struct _finddata_t t;
 long handle;
 if ((handle = (long)_findfirst(input_files, &t)) != -1)
 {
  char target_file[260];
  do
  {
   strcpy(target_file, t.name);
   char *dot_pos = strrchr(target_file, '.');
   printf("Processing: %s ...", target_file);
   if ( dot_pos ) *dot_pos = '/0';
   char templ[_MAX_PATH];
   strcpy(templ, target_file);
   strcat(target_file, ".BMP");
   pdt_load(&rec, t.name);
   pdt_decode(&rec, target_file);
   pdt_free(&rec);
   printf("Done./n");
  } while(_findnext(handle, &t) != -1);
 }
 return 0;
}

 

 

 

这篇关于PDT文件格式分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/740616

相关文章

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

【软考】希尔排序算法分析

目录 1. c代码2. 运行截图3. 运行解析 1. c代码 #include <stdio.h>#include <stdlib.h> void shellSort(int data[], int n){// 划分的数组,例如8个数则为[4, 2, 1]int *delta;int k;// i控制delta的轮次int i;// 临时变量,换值int temp;in

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通过IO+EXIT中断的方式进行霍尔传感器数据的读取。将IO口配置为上升沿+下降沿中断触发的方式。当霍尔传感器信号发生发生信号的变化就会触发中断在中断

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除

PostgreSQL核心功能特性与使用领域及场景分析

PostgreSQL有什么优点? 开源和免费 PostgreSQL是一个开源的数据库管理系统,可以免费使用和修改。这降低了企业的成本,并为开发者提供了一个活跃的社区和丰富的资源。 高度兼容 PostgreSQL支持多种操作系统(如Linux、Windows、macOS等)和编程语言(如C、C++、Java、Python、Ruby等),并提供了多种接口(如JDBC、ODBC、ADO.NET等

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据