Ejemplo n.º 1
0
static void handle_ani_icon(riff_tag_t *rtp, enum res_e type, int isswapped)
{
    cursor_dir_entry_t *cdp;
    cursor_header_t *chp;
    int count;
    int ctype;
    int i;
    static int once = 0;	/* This will trigger only once per file! */
    const char *anistr = type == res_aniico ? "icon" : "cursor";
    /* Notes:
     * Both cursor and icon directories are similar
     * Both cursor and icon headers are similar
     */

    chp = (cursor_header_t *)(rtp+1);
    cdp = (cursor_dir_entry_t *)(chp+1);
    count = isswapped ? BYTESWAP_WORD(chp->count) : chp->count;
    ctype = isswapped ? BYTESWAP_WORD(chp->type) : chp->type;
    chp->reserved	= BYTESWAP_WORD(chp->reserved);
    chp->type	= BYTESWAP_WORD(chp->type);
    chp->count	= BYTESWAP_WORD(chp->count);

    if(type == res_anicur && ctype != 2 && !once)
    {
        yywarning("Animated cursor contains invalid \"icon\" tag cursor-file (%d->%s)",
                  ctype,
                  ctype == 1 ? "icontype" : "?");
        once++;
    }
    else if(type == res_aniico && ctype != 1 && !once)
    {
        yywarning("Animated icon contains invalid \"icon\" tag icon-file (%d->%s)",
                  ctype,
                  ctype == 2 ? "cursortype" : "?");
        once++;
    }
    else if(ctype != 1 && ctype != 2 && !once)
    {
        yywarning("Animated %s contains invalid \"icon\" tag file-type (%d; neither icon nor cursor)", anistr, ctype);
        once++;
    }

    for(i = 0; i < count; i++)
    {
        DWORD ofs = isswapped ? BYTESWAP_DWORD(cdp[i].offset) : cdp[i].offset;
        DWORD sze = isswapped ? BYTESWAP_DWORD(cdp[i].ressize) : cdp[i].ressize;
        if(ofs > rtp->size || ofs+sze > rtp->size)
            yyerror("Animated %s's data corrupt", anistr);
        convert_bitmap((char *)chp + ofs, 0);
        cdp[i].xhot	= BYTESWAP_WORD(cdp->xhot);
        cdp[i].yhot	= BYTESWAP_WORD(cdp->yhot);
        cdp[i].ressize	= BYTESWAP_DWORD(cdp->ressize);
        cdp[i].offset	= BYTESWAP_DWORD(cdp->offset);
    }
}
Ejemplo n.º 2
0
Value* NSource::codeGen(Arendelle* arendelle)
{
	Value* nVal = name->codeGen(arendelle);
	std::string sName = static_cast<VString*>(nVal)->value;
	sourceStrCorrector(&sName);
	double sVal;
	if(arendelle->sourceExist(sName))
	{
		sVal = arendelle->getLastSourceSearch();
	}
	else
	{
		yywarning("Non Defined Source, Thought Zero(0) by Default!");
		sVal = 0;
	}
	std::cout<<std::endl<<"Access Source : "<<sName<<" -> "<<sVal<<std::endl;
	Value* val = new VFloat(sVal);
	return val;
}
Ejemplo n.º 3
0
void
add_Function(File * file, Function * func)
{
   int no;

   if (search_Coll(&file->Coll_functions_of_File, func, &no))
   {
		VAR(Function, fp, file->Coll_functions_of_File.items_of_Coll[no]);
      if (fp == mainFunction)
      {
	 char buf[80];

	 yywarning("declaration function with module name '%s'; force -n flag", fp->name_of_Function);
	 remove_Coll(&file->Coll_functions_of_File, fp);
	 snprintf(buf, sizeof(buf), "%s_m", fp->name_of_Function);
	 free(fp->name_of_Function);
	 fp->name_of_Function = strdup(buf);
	 insert_Coll(&file->Coll_functions_of_File, fp);

	 no = insert_Coll(&file->Coll_unsortedFunctions_of_File, func);
	 func->no_of_Function = no;
	 insert_Coll(&file->Coll_functions_of_File, func);

      }
      else
	 yyerror("function '%s' already defined near line %d file %s", fp->name_of_Function, fp->line_of_Function, fileName(fp->file_of_Function));
   }
   else if (!func->isPublic_of_Function && search_Coll(&file->Coll_externFunctions_of_File, func->name_of_Function, &no))
   {
      yyerror("static function '%s' already declared as external", func->name_of_Function);
   }
   else
   {
      no = insert_Coll(&file->Coll_unsortedFunctions_of_File, func);
      func->no_of_Function = no;
      insert_Coll(&file->Coll_functions_of_File, func);
   }
}
Ejemplo n.º 4
0
/*------------------------------------------------------------*/
void
select_residue_from_to (const char *item1, const char *item2)
{
  mol3d *mol;
  res3d *res;
  boolean within_sequence = FALSE;
  boolean first_is_known = FALSE;
  boolean first_was_aa;
  regexp *rx1, *rx2;
  int *flags;
#ifndef NDEBUG
  int old = count_residue_selections();
#endif

  assert (item1);
  assert (*item1);
  assert (item2);
  assert (*item2);

  if (str_eq (item1, item2)) {
    yyerror ("invalid from-to selection: same residue");
    return;
  }

  rx1 = compile_regexp (item1);
  rx2 = compile_regexp (item2);
  push_residue_selection();
  flags = current_residue_sel->flags;

  for (mol = first_molecule; mol; mol = mol->next) {
    for (res = mol->first; res; res = res->next) {
      if (within_sequence) {
	*flags++ = TRUE;
	if (regexec (rx2, res->name) != 0) within_sequence = FALSE;
      } else {
	within_sequence = regexec (rx1, res->name) != 0;
	if (within_sequence) {	/* kludge to deal with the silly PDB */
	  if (first_is_known) {	/* notion of allowing multiple residues */
	    if (first_was_aa) {	/* with the same name in a file */
	      if (res->code == 'X') within_sequence = FALSE;
	    }
	  } else {
	    first_was_aa = res->code != 'X';
	    first_is_known = TRUE;
	  }
	}
	*flags++ = within_sequence;
      }
    }
  }

  if (within_sequence) yywarning ("sequence segment not ended (residue selection \"from to\")");

  free (rx1);
  free (rx2);

#ifdef SELECT_DEBUG
  fprintf (stderr, "residue select from to: %i\n", select_residue_count());
#endif
#ifndef NDEBUG
  assert (count_residue_selections() == old + 1);
#endif
}
Ejemplo n.º 5
0
YR_STRING* yr_parser_reduce_string_declaration(
    yyscan_t yyscanner,
    int32_t string_flags,
    const char* identifier,
    SIZED_STRING* str)
{
  int min_atom_quality;
  int min_atom_quality_aux;
  int re_flags = 0;

  int32_t min_gap;
  int32_t max_gap;

  char message[512];

  YR_COMPILER* compiler = yyget_extra(yyscanner);
  YR_STRING* string = NULL;
  YR_STRING* aux_string;
  YR_STRING* prev_string;

  RE* re = NULL;
  RE* remainder_re;

  RE_ERROR re_error;

  // Determine if a string with the same identifier was already defined
  // by searching for the identifier in string_table.

  string = yr_hash_table_lookup(
      compiler->strings_table,
      identifier,
      NULL);

  if (string != NULL)
  {
    compiler->last_result = ERROR_DUPLICATED_STRING_IDENTIFIER;
    yr_compiler_set_error_extra_info(compiler, identifier);
    goto _exit;
  }

  // Empty strings are now allowed

  if (str->length == 0)
  {
    compiler->last_result = ERROR_EMPTY_STRING;
    yr_compiler_set_error_extra_info(compiler, identifier);
    goto _exit;
  }

  if (str->flags & SIZED_STRING_FLAGS_NO_CASE)
    string_flags |= STRING_GFLAGS_NO_CASE;

  if (str->flags & SIZED_STRING_FLAGS_DOT_ALL)
    re_flags |= RE_FLAGS_DOT_ALL;

  if (strcmp(identifier,"$") == 0)
    string_flags |= STRING_GFLAGS_ANONYMOUS;

  if (!(string_flags & STRING_GFLAGS_WIDE))
    string_flags |= STRING_GFLAGS_ASCII;

  if (string_flags & STRING_GFLAGS_NO_CASE)
    re_flags |= RE_FLAGS_NO_CASE;

  // The STRING_GFLAGS_SINGLE_MATCH flag indicates that finding
  // a single match for the string is enough. This is true in
  // most cases, except when the string count (#) and string offset (@)
  // operators are used. All strings are marked STRING_FLAGS_SINGLE_MATCH
  // initially, and unmarked later if required.

  string_flags |= STRING_GFLAGS_SINGLE_MATCH;

  // The STRING_GFLAGS_FIXED_OFFSET indicates that the string doesn't
  // need to be searched all over the file because the user is using the
  // "at" operator. The string must be searched at a fixed offset in the
  // file. All strings are marked STRING_GFLAGS_FIXED_OFFSET initially,
  // and unmarked later if required.

  string_flags |= STRING_GFLAGS_FIXED_OFFSET;

  if (string_flags & STRING_GFLAGS_HEXADECIMAL ||
      string_flags & STRING_GFLAGS_REGEXP)
  {
    if (string_flags & STRING_GFLAGS_HEXADECIMAL)
      compiler->last_result = yr_re_parse_hex(
          str->c_string, re_flags, &re, &re_error);
    else
      compiler->last_result = yr_re_parse(
          str->c_string, re_flags, &re, &re_error);

    if (compiler->last_result != ERROR_SUCCESS)
    {
      snprintf(
          message,
          sizeof(message),
          "invalid %s \"%s\": %s",
          (string_flags & STRING_GFLAGS_HEXADECIMAL) ?
              "hex string" : "regular expression",
          identifier,
          re_error.message);

      yr_compiler_set_error_extra_info(
          compiler, message);

      goto _exit;
    }

    if (re->flags & RE_FLAGS_FAST_HEX_REGEXP)
      string_flags |= STRING_GFLAGS_FAST_HEX_REGEXP;

    // Regular expressions in the strings section can't mix greedy and ungreedy
    // quantifiers like .* and .*?. That's because these regular expressions can
    // be matched forwards and/or backwards depending on the atom found, and we
    // need the regexp to be all-greedy or all-ungreedy to be able to properly
    // calculate the length of the match.

    if ((re->flags & RE_FLAGS_GREEDY) &&
        (re->flags & RE_FLAGS_UNGREEDY))
    {
      compiler->last_result = ERROR_INVALID_REGULAR_EXPRESSION;

      yr_compiler_set_error_extra_info(compiler,
          "greedy and ungreedy quantifiers can't be mixed in a regular "
          "expression");

      goto _exit;
    }

    if (re->flags & RE_FLAGS_GREEDY)
      string_flags |= STRING_GFLAGS_GREEDY_REGEXP;

    if (yr_re_contains_dot_star(re))
    {
      snprintf(
        message,
        sizeof(message),
        "%s contains .*, consider using .{N} with a reasonable value for N",
        identifier);

        yywarning(yyscanner, message);
    }

    compiler->last_result = yr_re_split_at_chaining_point(
        re, &re, &remainder_re, &min_gap, &max_gap);

    if (compiler->last_result != ERROR_SUCCESS)
      goto _exit;

    compiler->last_result = _yr_parser_write_string(
        identifier,
        string_flags,
        compiler,
        NULL,
        re,
        &string,
        &min_atom_quality);

    if (compiler->last_result != ERROR_SUCCESS)
      goto _exit;

    if (remainder_re != NULL)
    {
      string->g_flags |= STRING_GFLAGS_CHAIN_TAIL | STRING_GFLAGS_CHAIN_PART;
      string->chain_gap_min = min_gap;
      string->chain_gap_max = max_gap;
    }

    // Use "aux_string" from now on, we want to keep the value of "string"
    // because it will returned.

    aux_string = string;

    while (remainder_re != NULL)
    {
      // Destroy regexp pointed by 're' before yr_re_split_at_jmp
      // overwrites 're' with another value.

      yr_re_destroy(re);

      compiler->last_result = yr_re_split_at_chaining_point(
          remainder_re, &re, &remainder_re, &min_gap, &max_gap);

      if (compiler->last_result != ERROR_SUCCESS)
        goto _exit;

      prev_string = aux_string;

      compiler->last_result = _yr_parser_write_string(
          identifier,
          string_flags,
          compiler,
          NULL,
          re,
          &aux_string,
          &min_atom_quality_aux);

      if (compiler->last_result != ERROR_SUCCESS)
        goto _exit;

      if (min_atom_quality_aux < min_atom_quality)
        min_atom_quality = min_atom_quality_aux;

      aux_string->g_flags |= STRING_GFLAGS_CHAIN_PART;
      aux_string->chain_gap_min = min_gap;
      aux_string->chain_gap_max = max_gap;

      prev_string->chained_to = aux_string;

      // prev_string is now chained to aux_string, an string chained
      // to another one can't have a fixed offset, only the head of the
      // string chain can have a fixed offset.

      prev_string->g_flags &= ~STRING_GFLAGS_FIXED_OFFSET;
    }
  }
  else
  {
    compiler->last_result = _yr_parser_write_string(
        identifier,
        string_flags,
        compiler,
        str,
        NULL,
        &string,
        &min_atom_quality);

    if (compiler->last_result != ERROR_SUCCESS)
      goto _exit;
  }

  compiler->last_result = yr_hash_table_add(
      compiler->strings_table,
      identifier,
      NULL,
      string);

  if (compiler->last_result != ERROR_SUCCESS)
    goto _exit;

  if (min_atom_quality < 3 && compiler->callback != NULL)
  {
    snprintf(
        message,
        sizeof(message),
        "%s is slowing down scanning%s",
        string->identifier,
        min_atom_quality < 2 ? " (critical!)" : "");

    yywarning(yyscanner, message);
  }

_exit:

  if (re != NULL)
    yr_re_destroy(re);

  if (compiler->last_result != ERROR_SUCCESS)
    return NULL;

  return string;
}
Ejemplo n.º 6
0
static char *
tr_charset(Locale * lp, char *msg)
{
   if (lp && lp->charset && out_charset && strcasecmp(lp->charset, out_charset))
   {
#ifdef HAVE_ICONV
      char *rp, *ip, *op;

      int l, il, ol, rl;

      if (!lp->tr_inited)
      {
	 lp->it = iconv_open(out_charset, lp->charset);
	 lp->tr_inited = 1;
      }
      if (lp->it == (iconv_t) - 1)
	 return msg;
      il = l = strlen(msg);
      rl = ol = l * 3;
      rp = (char *) malloc(ol);
      ip = msg;
      op = rp;
      iconv(lp->it, &ip, (size_t *) & il, &op, (size_t *) & ol);
      rl -= ol;
      rp = (char *) realloc(rp, rl + 1);
      rp[rl] = 0;
      return rp;
#else
      char *rp;

      int i, rl;

      rl = strlen(msg);
      if (!lp->tr_inited)
      {
	 char *p1, *p2;

	 cons_CharsetEntry *cs1 = 0, *cs2 = 0;

	 int len1 = 0, len2 = 0;

	 int r1, r2;

	 p1 = lp->charset;
	 p2 = out_charset;

	 if ((r1 = load_charset_name(p1, &cs1, &len1)))
	 {
	    yywarning("cannot load charset '%s': %s", p1, strerror(errno));
	 }
	 if ((r2 = load_charset_name(p2, &cs2, &len2)))
	 {
	    yywarning("cannot load charset '%s': %s", p2, strerror(errno));
	 }

	 if (!r1 && !r2)
	 {
	    make_translation(cs1, len1, cs2, len2, lp->trans_tbl);
	 }
	 else
	 {
	    for (i = 0; i < 256; i++)
	       lp->trans_tbl[i] = i;
	 }
	 lp->tr_inited = 1;
      }
      rp = (char *) malloc(rl + 1);
      for (i = 0; i < rl; i++)
	 rp[i] = lp->trans_tbl[((unsigned char *) msg)[i]];
      rp[rl] = 0;
      return rp;
#endif
   }
   else
      return msg;
}
Ejemplo n.º 7
0
int yr_parser_reduce_rule_declaration_phase_2(
    yyscan_t yyscanner,
    YR_RULE* rule)
{
  uint32_t max_strings_per_rule;
  uint32_t strings_in_rule = 0;
  uint8_t* nop_inst_addr = NULL;

  int result;

  YR_FIXUP *fixup;
  YR_STRING* string;
  YR_COMPILER* compiler = yyget_extra(yyscanner);

  yr_get_configuration(
      YR_CONFIG_MAX_STRINGS_PER_RULE,
      (void*) &max_strings_per_rule);

  // Show warning if the rule is generating too many atoms. The warning is
  // shown if the number of atoms is greater than 20 times the maximum number
  // of strings allowed for a rule, as 20 is minimum number of atoms generated
  // for a string using *nocase*, *ascii* and *wide* modifiers simultaneosly.

  if (rule->num_atoms > YR_ATOMS_PER_RULE_WARNING_THRESHOLD)
  {
    yywarning(
        yyscanner,
        "rule %s is slowing down scanning",
        rule->identifier);
  }

  // Check for unreferenced (unused) strings.
  string = rule->strings;

  while (!STRING_IS_NULL(string))
  {
    // Only the heading fragment in a chain of strings (the one with
    // chained_to == NULL) must be referenced. All other fragments
    // are never marked as referenced.

    if (!STRING_IS_REFERENCED(string) &&
        string->chained_to == NULL)
    {
      yr_compiler_set_error_extra_info(compiler, string->identifier);
      return ERROR_UNREFERENCED_STRING;
    }

    strings_in_rule++;

    if (strings_in_rule > max_strings_per_rule)
    {
      yr_compiler_set_error_extra_info(compiler, rule->identifier);
      return ERROR_TOO_MANY_STRINGS;
    }

    string = (YR_STRING*) yr_arena_next_address(
        compiler->strings_arena,
        string,
        sizeof(YR_STRING));
  }

  result = yr_parser_emit_with_arg_reloc(
      yyscanner,
      OP_MATCH_RULE,
      rule,
      NULL,
      NULL);

  // Generate a do-nothing instruction (NOP) in order to get its address
  // and use it as the destination for the OP_INIT_RULE skip jump. We can not
  // simply use the address of the OP_MATCH_RULE instruction +1 because we
  // can't be sure that the instruction following the OP_MATCH_RULE is going to
  // be in the same arena page. As we don't have a reliable way of getting the
  // address of the next instruction we generate the OP_NOP.

  if (result == ERROR_SUCCESS)
    result = yr_parser_emit(yyscanner, OP_NOP, &nop_inst_addr);

  fixup = compiler->fixup_stack_head;
  *(void**)(fixup->address) = (void*) nop_inst_addr;
  compiler->fixup_stack_head = fixup->next;
  yr_free(fixup);

  return result;
}
Ejemplo n.º 8
0
static void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur)
{
    int cnt;
    int i;
    cursor_t *cur;
    cursor_t *list = NULL;
    cursor_header_t *ch = (cursor_header_t *)rd->data;
    int swap = 0;

    if(ch->type == 2)
        swap = 0;
    else if(BYTESWAP_WORD(ch->type) == 2)
        swap = 1;
    else
        yyerror("Cursor resource data has invalid type id %d", ch->type);
    cnt = swap ? BYTESWAP_WORD(ch->count) : ch->count;
    for(i = 0; i < cnt; i++)
    {
        cursor_dir_entry_t cde;
        BITMAPINFOHEADER info;
        memcpy(&cde, rd->data + sizeof(cursor_header_t)
               + i*sizeof(cursor_dir_entry_t), sizeof(cde));

        cur = new_cursor();
        cur->id = alloc_cursor_id(curg->lvc.language);
        cur->lvc = curg->lvc;
        if(swap)
        {
            cde.offset = BYTESWAP_DWORD(cde.offset);
            cde.ressize= BYTESWAP_DWORD(cde.ressize);
        }
        if(cde.offset > rd->size
                || cde.offset + cde.ressize > rd->size)
            yyerror("Cursor resource data corrupt");
        cur->width = cde.width;
        cur->height = cde.height;
        cur->nclr = cde.nclr;
        memcpy(&info, rd->data + cde.offset, sizeof(info));
        convert_bitmap((char *)&info, 0);
        memcpy(rd->data + cde.offset, &info, sizeof(info));
        /* The bitmap is in destination byteorder. We want native for our structures */
        switch(byteorder)
        {
#ifdef WORDS_BIGENDIAN
        case WRC_BO_LITTLE:
#else
        case WRC_BO_BIG:
#endif
            cur->planes = BYTESWAP_WORD(info.biPlanes);
            cur->bits = BYTESWAP_WORD(info.biBitCount);
            break;
        default:
            cur->planes = info.biPlanes;
            cur->bits = info.biBitCount;
        }
        if(!win32 && (cur->planes != 1 || cur->bits != 1))
            yywarning("Win16 cursor contains colors");
        cur->xhot = swap ? BYTESWAP_WORD(cde.xhot) : cde.xhot;
        cur->yhot = swap ? BYTESWAP_WORD(cde.yhot) : cde.yhot;
        cur->data = new_raw_data();
        copy_raw_data(cur->data, rd, cde.offset, cde.ressize);
        if(!list)
        {
            list = cur;
        }
        else
        {
            cur->next = list;
            list->prev = cur;
            list = cur;
        }
    }
    curg->cursorlist = list;
    *ncur = cnt;
}
Ejemplo n.º 9
0
static int convert_bitmap(char *data, int size)
{
    BITMAPINFOHEADER *bih = (BITMAPINFOHEADER *)data;
    BITMAPV4HEADER *b4h = (BITMAPV4HEADER *)data;
    BITMAPOS2HEADER *boh = (BITMAPOS2HEADER *)data;
    int type = 0;
    int returnSize = 0;           /* size to be returned */
#ifdef WORDS_BIGENDIAN
    DWORD bisizel = BYTESWAP_DWORD(sizeof(BITMAPINFOHEADER));
    DWORD b4sizel = BYTESWAP_DWORD(sizeof(BITMAPV4HEADER));
    DWORD bosizel = BYTESWAP_DWORD(sizeof(BITMAPOS2HEADER));
    DWORD bisizeb = sizeof(BITMAPINFOHEADER);
    DWORD b4sizeb = sizeof(BITMAPV4HEADER);
    DWORD bosizeb = sizeof(BITMAPOS2HEADER);
#else
    DWORD bisizel = sizeof(BITMAPINFOHEADER);
    DWORD b4sizel = sizeof(BITMAPV4HEADER);
    DWORD bosizel = sizeof(BITMAPOS2HEADER);
    DWORD bisizeb = BYTESWAP_DWORD(sizeof(BITMAPINFOHEADER));
    DWORD b4sizeb = BYTESWAP_DWORD(sizeof(BITMAPV4HEADER));
    DWORD bosizeb = BYTESWAP_DWORD(sizeof(BITMAPOS2HEADER));
#endif


    /*
     * Originally the bih and b4h pointers were simply incremented here,
     * and memmoved at the end of the function.  This causes alignment
     * issues on solaris, so we do the memmove here rather than at the end.
     */
    if(data[0] == 'B' && data[1] == 'M')
    {
        /* Little endian signature */
        memmove(data, data+sizeof(BITMAPFILEHEADER), size - sizeof(BITMAPFILEHEADER));
        returnSize = sizeof(BITMAPFILEHEADER);
    }
    else if(data[0] == 'M' && data[1] == 'B')
    {
        type |= FL_SIGBE;	/* Big endian signature */
        memmove(data, data+sizeof(BITMAPFILEHEADER), size - sizeof(BITMAPFILEHEADER));
        returnSize = sizeof(BITMAPFILEHEADER);

    }

    if(bih->biSize == bisizel)
    {
        /* Little endian */
    }
    else if(bih->biSize == bisizeb)
    {
        type |= FL_SIZEBE;
    }
    else if(bih->biSize == b4sizel)
    {
        type |= FL_V4;
    }
    else if(bih->biSize == b4sizeb)
    {
        type |= FL_SIZEBE | FL_V4;
    }
    else if(!bih->biSize || bih->biSize == bosizel)
    {
        type |= FL_OS2;
    }
    else if(bih->biSize == bosizeb)
    {
        type |= FL_SIZEBE | FL_OS2;
    }
    else
        yyerror("Invalid bitmap format, bih->biSize = %ld", bih->biSize);

    switch(type)
    {
    default:
        break;
    case FL_SIZEBE:
    case FL_SIZEBE | FL_V4:
    case FL_SIZEBE | FL_OS2:
        yywarning("Bitmap v%c signature little-endian, but size big-endian", type & FL_V4 ? '4' : '3');
        break;
    case FL_SIGBE:
    case FL_SIGBE | FL_V4:
    case FL_SIGBE | FL_OS2:
        yywarning("Bitmap v%c signature big-endian, but size little-endian", type & FL_V4 ? '4' : '3');
        break;
    }

    switch(byteorder)
    {
#ifdef WORDS_BIGENDIAN
    default:
#endif
    case WRC_BO_BIG:
        if(!(type & FL_SIZEBE))
        {
            if(type & FL_V4)
                convert_bitmap_swap_v4(b4h);
            else if(type & FL_OS2)
            {
                convert_bitmap_swap_os2(boh);
            }
            else
                convert_bitmap_swap_v3(bih);
        }
        break;
#ifndef WORDS_BIGENDIAN
    default:
#endif
    case WRC_BO_LITTLE:
        if(type & FL_SIZEBE)
        {
            if(type & FL_V4)
                convert_bitmap_swap_v4(b4h);
            else if(type & FL_OS2)
            {
                convert_bitmap_swap_os2(boh);
            }
            else
                convert_bitmap_swap_v3(bih);
        }
        break;
    }

    if(size && (void *)data != (void *)bih)
    {
        /* We have the fileheader still attached, remove it */
        memmove(data, data+sizeof(BITMAPFILEHEADER), size - sizeof(BITMAPFILEHEADER));
        return sizeof(BITMAPFILEHEADER);
    }
    return returnSize;
}